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

#include "vm/exceptions.h"
#include "vm/dart_entry.h"
#include "vm/isolate.h"
#include "vm/object.h"
#include "vm/raw_object.h"
#include "vm/symbols.h"
#include "vm/visitor.h"

namespace dart {

ObjectStore::ObjectStore()
  : object_class_(Class::null()),
    object_type_(Type::null()),
    null_class_(Class::null()),
    null_type_(Type::null()),
    function_type_(Type::null()),
    function_impl_type_(Type::null()),
    number_type_(Type::null()),
    int_type_(Type::null()),
    integer_implementation_class_(Class::null()),
    smi_class_(Class::null()),
    smi_type_(Type::null()),
    mint_class_(Class::null()),
    mint_type_(Type::null()),
    bigint_class_(Class::null()),
    double_class_(Class::null()),
    double_type_(Type::null()),
    float32x4_type_(Type::null()),
    int32x4_type_(Type::null()),
    float64x2_type_(Type::null()),
    string_type_(Type::null()),
    future_class_(Class::null()),
    completer_class_(Class::null()),
    stream_iterator_class_(Class::null()),
    symbol_class_(Class::null()),
    one_byte_string_class_(Class::null()),
    two_byte_string_class_(Class::null()),
    external_one_byte_string_class_(Class::null()),
    external_two_byte_string_class_(Class::null()),
    bool_type_(Type::null()),
    bool_class_(Class::null()),
    array_class_(Class::null()),
    array_type_(Type::null()),
    immutable_array_class_(Class::null()),
    growable_object_array_class_(Class::null()),
    linked_hash_map_class_(Class::null()),
    float32x4_class_(Class::null()),
    int32x4_class_(Class::null()),
    float64x2_class_(Class::null()),
    error_class_(Class::null()),
    weak_property_class_(Class::null()),
    symbol_table_(Array::null()),
    canonical_type_arguments_(Array::null()),
    async_library_(Library::null()),
    builtin_library_(Library::null()),
    core_library_(Library::null()),
    collection_library_(Library::null()),
    convert_library_(Library::null()),
    developer_library_(Library::null()),
    internal_library_(Library::null()),
    isolate_library_(Library::null()),
    math_library_(Library::null()),
    mirrors_library_(Library::null()),
    native_wrappers_library_(Library::null()),
    root_library_(Library::null()),
    typed_data_library_(Library::null()),
    vmservice_library_(Library::null()),
    libraries_(GrowableObjectArray::null()),
    pending_classes_(GrowableObjectArray::null()),
    pending_functions_(GrowableObjectArray::null()),
    pending_deferred_loads_(GrowableObjectArray::null()),
    resume_capabilities_(GrowableObjectArray::null()),
    exit_listeners_(GrowableObjectArray::null()),
    error_listeners_(GrowableObjectArray::null()),
    sticky_error_(Error::null()),
    empty_context_(Context::null()),
    stack_overflow_(Instance::null()),
    out_of_memory_(Instance::null()),
    preallocated_unhandled_exception_(UnhandledException::null()),
    preallocated_stack_trace_(Stacktrace::null()),
    lookup_port_handler_(Function::null()),
    empty_uint32_array_(TypedData::null()),
    handle_message_function_(Function::null()),
    library_load_error_table_(Array::null()),
    compile_time_constants_(Array::null()),
    megamorphic_cache_table_(GrowableObjectArray::null()),
    megamorphic_miss_code_(Code::null()),
    megamorphic_miss_function_(Function::null()) {
  for (RawObject** current = from(); current <= to(); current++) {
    ASSERT(*current == Object::null());
  }
}


ObjectStore::~ObjectStore() {
}


void ObjectStore::VisitObjectPointers(ObjectPointerVisitor* visitor) {
  ASSERT(visitor != NULL);
  visitor->VisitPointers(from(), to());
}


void ObjectStore::Init(Isolate* isolate) {
  ASSERT(isolate->object_store() == NULL);
  ObjectStore* store = new ObjectStore();
  isolate->set_object_store(store);
}


bool ObjectStore::PreallocateObjects() {
  Thread* thread = Thread::Current();
  Isolate* isolate = thread->isolate();
  Zone* zone = thread->zone();
  ASSERT(isolate != NULL && isolate->object_store() == this);
  if (this->stack_overflow() != Instance::null()) {
    ASSERT(this->out_of_memory() != Instance::null());
    ASSERT(this->preallocated_stack_trace() != Stacktrace::null());
    return true;
  }
  ASSERT(this->stack_overflow() == Instance::null());
  ASSERT(this->out_of_memory() == Instance::null());
  ASSERT(this->preallocated_stack_trace() == Stacktrace::null());

  ASSERT(this->pending_functions() == GrowableObjectArray::null());
  this->pending_functions_ = GrowableObjectArray::New();
  this->pending_deferred_loads_ = GrowableObjectArray::New();

  this->resume_capabilities_ = GrowableObjectArray::New();
  this->exit_listeners_ = GrowableObjectArray::New();
  this->error_listeners_ = GrowableObjectArray::New();

  Object& result = Object::Handle();
  const Library& library = Library::Handle(Library::CoreLibrary());

  result = DartLibraryCalls::InstanceCreate(library,
                                            Symbols::StackOverflowError(),
                                            Symbols::Dot(),
                                            Object::empty_array());
  if (result.IsError()) {
    return false;
  }
  set_stack_overflow(Instance::Cast(result));

  result = DartLibraryCalls::InstanceCreate(library,
                                            Symbols::OutOfMemoryError(),
                                            Symbols::Dot(),
                                            Object::empty_array());
  if (result.IsError()) {
    return false;
  }
  set_out_of_memory(Instance::Cast(result));

  // Allocate pre-allocated unhandled exception object initialized with the
  // pre-allocated OutOfMemoryError.
  const UnhandledException& unhandled_exception = UnhandledException::Handle(
      UnhandledException::New(Instance::Cast(result),
                              Stacktrace::Handle(zone)));
  set_preallocated_unhandled_exception(unhandled_exception);

  const Array& code_array = Array::Handle(zone,
      Array::New(Stacktrace::kPreallocatedStackdepth, Heap::kOld));
  const Array& pc_offset_array = Array::Handle(zone,
      Array::New(Stacktrace::kPreallocatedStackdepth, Heap::kOld));
  const Stacktrace& stack_trace = Stacktrace::Handle(zone,
      Stacktrace::New(code_array, pc_offset_array));
  // Expansion of inlined functions requires additional memory at run time,
  // avoid it.
  stack_trace.set_expand_inlined(false);
  set_preallocated_stack_trace(stack_trace);

  return true;
}


void ObjectStore::InitKnownObjects() {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  Isolate* isolate = thread->isolate();
  ASSERT(isolate != NULL && isolate->object_store() == this);

  const Library& async_lib = Library::Handle(async_library());
  ASSERT(!async_lib.IsNull());
  Class& cls = Class::Handle(zone);
  cls = async_lib.LookupClass(Symbols::Future());
  ASSERT(!cls.IsNull());
  set_future_class(cls);
  cls = async_lib.LookupClass(Symbols::Completer());
  ASSERT(!cls.IsNull());
  set_completer_class(cls);
  cls = async_lib.LookupClass(Symbols::StreamIterator());
  ASSERT(!cls.IsNull());
  set_stream_iterator_class(cls);

  const Library& internal_lib = Library::Handle(internal_library());
  cls = internal_lib.LookupClass(Symbols::Symbol());
  set_symbol_class(cls);
}

}  // namespace dart
