// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_FACTORY_H_
#define V8_FACTORY_H_

#include "src/feedback-vector.h"
#include "src/globals.h"
#include "src/isolate.h"
#include "src/messages.h"

namespace v8 {
namespace internal {

class BoilerplateDescription;
class ConstantElementsPair;

enum FunctionMode {
  // With prototype.
  FUNCTION_WITH_WRITEABLE_PROTOTYPE,
  FUNCTION_WITH_READONLY_PROTOTYPE,
  // Without prototype.
  FUNCTION_WITHOUT_PROTOTYPE
};

// Interface for handle based allocation.
class V8_EXPORT_PRIVATE Factory final {
 public:
  Handle<Oddball> NewOddball(Handle<Map> map, const char* to_string,
                             Handle<Object> to_number, const char* type_of,
                             byte kind);

  // Allocates a fixed array initialized with undefined values.
  Handle<FixedArray> NewFixedArray(int size,
                                   PretenureFlag pretenure = NOT_TENURED);
  // Tries allocating a fixed array initialized with undefined values.
  // In case of an allocation failure (OOM) an empty handle is returned.
  // The caller has to manually signal an
  // v8::internal::Heap::FatalProcessOutOfMemory typically by calling
  // NewFixedArray as a fallback.
  MUST_USE_RESULT
  MaybeHandle<FixedArray> TryNewFixedArray(
      int size, PretenureFlag pretenure = NOT_TENURED);

  // Allocate a new fixed array with non-existing entries (the hole).
  Handle<FixedArray> NewFixedArrayWithHoles(
      int size,
      PretenureFlag pretenure = NOT_TENURED);

  // Allocates an uninitialized fixed array. It must be filled by the caller.
  Handle<FixedArray> NewUninitializedFixedArray(int size);

  // Allocates a fixed array for name-value pairs of boilerplate properties and
  // calculates the number of properties we need to store in the backing store.
  Handle<BoilerplateDescription> NewBoilerplateDescription(int boilerplate,
                                                           int all_properties,
                                                           int index_keys,
                                                           bool has_seen_proto);

  // Allocate a new uninitialized fixed double array.
  // The function returns a pre-allocated empty fixed array for capacity = 0,
  // so the return type must be the general fixed array class.
  Handle<FixedArrayBase> NewFixedDoubleArray(
      int size,
      PretenureFlag pretenure = NOT_TENURED);

  // Allocate a new fixed double array with hole values.
  Handle<FixedArrayBase> NewFixedDoubleArrayWithHoles(
      int size,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<FrameArray> NewFrameArray(int number_of_frames,
                                   PretenureFlag pretenure = NOT_TENURED);

  Handle<OrderedHashSet> NewOrderedHashSet();
  Handle<OrderedHashMap> NewOrderedHashMap();

  // Create a new boxed value.
  Handle<Box> NewBox(Handle<Object> value);

  // Create a new PrototypeInfo struct.
  Handle<PrototypeInfo> NewPrototypeInfo();

  // Create a new Tuple2 struct.
  Handle<Tuple2> NewTuple2(Handle<Object> value1, Handle<Object> value2);

  // Create a new Tuple3 struct.
  Handle<Tuple3> NewTuple3(Handle<Object> value1, Handle<Object> value2,
                           Handle<Object> value3);

  // Create a new ContextExtension struct.
  Handle<ContextExtension> NewContextExtension(Handle<ScopeInfo> scope_info,
                                               Handle<Object> extension);

  // Create a new ConstantElementsPair struct.
  Handle<ConstantElementsPair> NewConstantElementsPair(
      ElementsKind elements_kind, Handle<FixedArrayBase> constant_values);

  // Create a pre-tenured empty AccessorPair.
  Handle<AccessorPair> NewAccessorPair();

  // Create an empty TypeFeedbackInfo.
  Handle<TypeFeedbackInfo> NewTypeFeedbackInfo();

  // Finds the internalized copy for string in the string table.
  // If not found, a new string is added to the table and returned.
  Handle<String> InternalizeUtf8String(Vector<const char> str);
  Handle<String> InternalizeUtf8String(const char* str) {
    return InternalizeUtf8String(CStrVector(str));
  }

  Handle<String> InternalizeOneByteString(Vector<const uint8_t> str);
  Handle<String> InternalizeOneByteString(
      Handle<SeqOneByteString>, int from, int length);

  Handle<String> InternalizeTwoByteString(Vector<const uc16> str);

  template<class StringTableKey>
  Handle<String> InternalizeStringWithKey(StringTableKey* key);

  // Internalized strings are created in the old generation (data space).
  Handle<String> InternalizeString(Handle<String> string) {
    if (string->IsInternalizedString()) return string;
    return StringTable::LookupString(isolate(), string);
  }

  Handle<Name> InternalizeName(Handle<Name> name) {
    if (name->IsUniqueName()) return name;
    return StringTable::LookupString(isolate(), Handle<String>::cast(name));
  }

  // String creation functions.  Most of the string creation functions take
  // a Heap::PretenureFlag argument to optionally request that they be
  // allocated in the old generation.  The pretenure flag defaults to
  // DONT_TENURE.
  //
  // Creates a new String object.  There are two String encodings: one-byte and
  // two-byte.  One should choose between the three string factory functions
  // based on the encoding of the string buffer that the string is
  // initialized from.
  //   - ...FromOneByte initializes the string from a buffer that is Latin1
  //     encoded (it does not check that the buffer is Latin1 encoded) and
  //     the result will be Latin1 encoded.
  //   - ...FromUtf8 initializes the string from a buffer that is UTF-8
  //     encoded.  If the characters are all ASCII characters, the result
  //     will be Latin1 encoded, otherwise it will converted to two-byte.
  //   - ...FromTwoByte initializes the string from a buffer that is two-byte
  //     encoded.  If the characters are all Latin1 characters, the result
  //     will be converted to Latin1, otherwise it will be left as two-byte.
  //
  // One-byte strings are pretenured when used as keys in the SourceCodeCache.
  MUST_USE_RESULT MaybeHandle<String> NewStringFromOneByte(
      Vector<const uint8_t> str, PretenureFlag pretenure = NOT_TENURED);

  template <size_t N>
  inline Handle<String> NewStringFromStaticChars(
      const char (&str)[N], PretenureFlag pretenure = NOT_TENURED) {
    DCHECK(N == StrLength(str) + 1);
    return NewStringFromOneByte(STATIC_CHAR_VECTOR(str), pretenure)
        .ToHandleChecked();
  }

  inline Handle<String> NewStringFromAsciiChecked(
      const char* str,
      PretenureFlag pretenure = NOT_TENURED) {
    return NewStringFromOneByte(
        OneByteVector(str), pretenure).ToHandleChecked();
  }


  // Allocates and fully initializes a String.  There are two String encodings:
  // one-byte and two-byte. One should choose between the threestring
  // allocation functions based on the encoding of the string buffer used to
  // initialized the string.
  //   - ...FromOneByte initializes the string from a buffer that is Latin1
  //     encoded (it does not check that the buffer is Latin1 encoded) and the
  //     result will be Latin1 encoded.
  //   - ...FromUTF8 initializes the string from a buffer that is UTF-8
  //     encoded.  If the characters are all ASCII characters, the result
  //     will be Latin1 encoded, otherwise it will converted to two-byte.
  //   - ...FromTwoByte initializes the string from a buffer that is two-byte
  //     encoded.  If the characters are all Latin1 characters, the
  //     result will be converted to Latin1, otherwise it will be left as
  //     two-byte.

  // TODO(dcarney): remove this function.
  MUST_USE_RESULT inline MaybeHandle<String> NewStringFromAscii(
      Vector<const char> str,
      PretenureFlag pretenure = NOT_TENURED) {
    return NewStringFromOneByte(Vector<const uint8_t>::cast(str), pretenure);
  }

  // UTF8 strings are pretenured when used for regexp literal patterns and
  // flags in the parser.
  MUST_USE_RESULT MaybeHandle<String> NewStringFromUtf8(
      Vector<const char> str, PretenureFlag pretenure = NOT_TENURED);

  MUST_USE_RESULT MaybeHandle<String> NewStringFromUtf8SubString(
      Handle<SeqOneByteString> str, int begin, int end,
      PretenureFlag pretenure = NOT_TENURED);

  MUST_USE_RESULT MaybeHandle<String> NewStringFromTwoByte(
      Vector<const uc16> str, PretenureFlag pretenure = NOT_TENURED);

  MUST_USE_RESULT MaybeHandle<String> NewStringFromTwoByte(
      const ZoneVector<uc16>* str, PretenureFlag pretenure = NOT_TENURED);

  Handle<JSStringIterator> NewJSStringIterator(Handle<String> string);

  // Allocates an internalized string in old space based on the character
  // stream.
  Handle<String> NewInternalizedStringFromUtf8(Vector<const char> str,
                                               int chars, uint32_t hash_field);

  Handle<String> NewOneByteInternalizedString(Vector<const uint8_t> str,
                                              uint32_t hash_field);

  Handle<String> NewOneByteInternalizedSubString(
      Handle<SeqOneByteString> string, int offset, int length,
      uint32_t hash_field);

  Handle<String> NewTwoByteInternalizedString(Vector<const uc16> str,
                                              uint32_t hash_field);

  Handle<String> NewInternalizedStringImpl(Handle<String> string, int chars,
                                           uint32_t hash_field);

  // Compute the matching internalized string map for a string if possible.
  // Empty handle is returned if string is in new space or not flattened.
  MUST_USE_RESULT MaybeHandle<Map> InternalizedStringMapForString(
      Handle<String> string);

  // Creates an internalized copy of an external string. |string| must be
  // of type StringClass.
  template <class StringClass>
  Handle<StringClass> InternalizeExternalString(Handle<String> string);

  // Allocates and partially initializes an one-byte or two-byte String. The
  // characters of the string are uninitialized. Currently used in regexp code
  // only, where they are pretenured.
  MUST_USE_RESULT MaybeHandle<SeqOneByteString> NewRawOneByteString(
      int length,
      PretenureFlag pretenure = NOT_TENURED);
  MUST_USE_RESULT MaybeHandle<SeqTwoByteString> NewRawTwoByteString(
      int length,
      PretenureFlag pretenure = NOT_TENURED);

  // Creates a single character string where the character has given code.
  // A cache is used for Latin1 codes.
  Handle<String> LookupSingleCharacterStringFromCode(uint32_t code);

  // Create a new cons string object which consists of a pair of strings.
  MUST_USE_RESULT MaybeHandle<String> NewConsString(Handle<String> left,
                                                    Handle<String> right);

  // Create or lookup a single characters tring made up of a utf16 surrogate
  // pair.
  Handle<String> NewSurrogatePairString(uint16_t lead, uint16_t trail);

  // Create a new string object which holds a proper substring of a string.
  Handle<String> NewProperSubString(Handle<String> str,
                                    int begin,
                                    int end);

  // Create a new string object which holds a substring of a string.
  Handle<String> NewSubString(Handle<String> str, int begin, int end) {
    if (begin == 0 && end == str->length()) return str;
    return NewProperSubString(str, begin, end);
  }

  // Creates a new external String object.  There are two String encodings
  // in the system: one-byte and two-byte.  Unlike other String types, it does
  // not make sense to have a UTF-8 factory function for external strings,
  // because we cannot change the underlying buffer.  Note that these strings
  // are backed by a string resource that resides outside the V8 heap.
  MUST_USE_RESULT MaybeHandle<String> NewExternalStringFromOneByte(
      const ExternalOneByteString::Resource* resource);
  MUST_USE_RESULT MaybeHandle<String> NewExternalStringFromTwoByte(
      const ExternalTwoByteString::Resource* resource);
  // Create a new external string object for one-byte encoded native script.
  // It does not cache the resource data pointer.
  Handle<ExternalOneByteString> NewNativeSourceString(
      const ExternalOneByteString::Resource* resource);

  // Create a symbol.
  Handle<Symbol> NewSymbol();
  Handle<Symbol> NewPrivateSymbol();

  // Create a global (but otherwise uninitialized) context.
  Handle<Context> NewNativeContext();

  // Create a script context.
  Handle<Context> NewScriptContext(Handle<JSFunction> function,
                                   Handle<ScopeInfo> scope_info);

  // Create an empty script context table.
  Handle<ScriptContextTable> NewScriptContextTable();

  // Create a module context.
  Handle<Context> NewModuleContext(Handle<Module> module,
                                   Handle<JSFunction> function,
                                   Handle<ScopeInfo> scope_info);

  // Create a function or eval context.
  Handle<Context> NewFunctionContext(int length, Handle<JSFunction> function,
                                     ScopeType scope_type);

  // Create a catch context.
  Handle<Context> NewCatchContext(Handle<JSFunction> function,
                                  Handle<Context> previous,
                                  Handle<ScopeInfo> scope_info,
                                  Handle<String> name,
                                  Handle<Object> thrown_object);

  // Create a 'with' context.
  Handle<Context> NewWithContext(Handle<JSFunction> function,
                                 Handle<Context> previous,
                                 Handle<ScopeInfo> scope_info,
                                 Handle<JSReceiver> extension);

  Handle<Context> NewDebugEvaluateContext(Handle<Context> previous,
                                          Handle<ScopeInfo> scope_info,
                                          Handle<JSReceiver> extension,
                                          Handle<Context> wrapped,
                                          Handle<StringSet> whitelist);

  // Create a block context.
  Handle<Context> NewBlockContext(Handle<JSFunction> function,
                                  Handle<Context> previous,
                                  Handle<ScopeInfo> scope_info);

  // Allocate a new struct.  The struct is pretenured (allocated directly in
  // the old generation).
  Handle<Struct> NewStruct(InstanceType type);

  Handle<AliasedArgumentsEntry> NewAliasedArgumentsEntry(
      int aliased_context_slot);

  Handle<AccessorInfo> NewAccessorInfo();

  Handle<Script> NewScript(Handle<String> source);

  Handle<BreakPointInfo> NewBreakPointInfo(int source_position);

  // Foreign objects are pretenured when allocated by the bootstrapper.
  Handle<Foreign> NewForeign(Address addr,
                             PretenureFlag pretenure = NOT_TENURED);

  // Allocate a new foreign object.  The foreign is pretenured (allocated
  // directly in the old generation).
  Handle<Foreign> NewForeign(const AccessorDescriptor* foreign);

  Handle<ByteArray> NewByteArray(int length,
                                 PretenureFlag pretenure = NOT_TENURED);

  Handle<BytecodeArray> NewBytecodeArray(int length, const byte* raw_bytecodes,
                                         int frame_size, int parameter_count,
                                         Handle<FixedArray> constant_pool);

  Handle<FixedTypedArrayBase> NewFixedTypedArrayWithExternalPointer(
      int length, ExternalArrayType array_type, void* external_pointer,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<FixedTypedArrayBase> NewFixedTypedArray(
      int length, ExternalArrayType array_type, bool initialize,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<Cell> NewCell(Handle<Object> value);

  Handle<PropertyCell> NewPropertyCell();

  Handle<WeakCell> NewWeakCell(Handle<HeapObject> value);

  Handle<TransitionArray> NewTransitionArray(int capacity);

  // Allocate a tenured AllocationSite. It's payload is null.
  Handle<AllocationSite> NewAllocationSite();

  Handle<Map> NewMap(
      InstanceType type,
      int instance_size,
      ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND);

  Handle<HeapObject> NewFillerObject(int size,
                                     bool double_align,
                                     AllocationSpace space);

  Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function);

  Handle<JSObject> CopyJSObject(Handle<JSObject> object);

  Handle<JSObject> CopyJSObjectWithAllocationSite(Handle<JSObject> object,
                                                  Handle<AllocationSite> site);

  Handle<FixedArray> CopyFixedArrayWithMap(Handle<FixedArray> array,
                                           Handle<Map> map);

  Handle<FixedArray> CopyFixedArrayAndGrow(
      Handle<FixedArray> array, int grow_by,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<FixedArray> CopyFixedArrayUpTo(Handle<FixedArray> array, int new_len,
                                        PretenureFlag pretenure = NOT_TENURED);

  Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);

  // This method expects a COW array in new space, and creates a copy
  // of it in old space.
  Handle<FixedArray> CopyAndTenureFixedCOWArray(Handle<FixedArray> array);

  Handle<FixedDoubleArray> CopyFixedDoubleArray(
      Handle<FixedDoubleArray> array);

  // Numbers (e.g. literals) are pretenured by the parser.
  // The return value may be a smi or a heap number.
  Handle<Object> NewNumber(double value,
                           PretenureFlag pretenure = NOT_TENURED);

  Handle<Object> NewNumberFromInt(int32_t value,
                                  PretenureFlag pretenure = NOT_TENURED);
  Handle<Object> NewNumberFromUint(uint32_t value,
                                  PretenureFlag pretenure = NOT_TENURED);
  Handle<Object> NewNumberFromSize(size_t value,
                                   PretenureFlag pretenure = NOT_TENURED) {
    // We can't use Smi::IsValid() here because that operates on a signed
    // intptr_t, and casting from size_t could create a bogus sign bit.
    if (value <= static_cast<size_t>(Smi::kMaxValue)) {
      return Handle<Object>(Smi::FromIntptr(static_cast<intptr_t>(value)),
                            isolate());
    }
    return NewNumber(static_cast<double>(value), pretenure);
  }
  Handle<Object> NewNumberFromInt64(int64_t value,
                                    PretenureFlag pretenure = NOT_TENURED) {
    if (value <= std::numeric_limits<int32_t>::max() &&
        value >= std::numeric_limits<int32_t>::min() &&
        Smi::IsValid(static_cast<int32_t>(value))) {
      return Handle<Object>(Smi::FromInt(static_cast<int32_t>(value)),
                            isolate());
    }
    return NewNumber(static_cast<double>(value), pretenure);
  }
  Handle<HeapNumber> NewHeapNumber(double value, MutableMode mode = IMMUTABLE,
                                   PretenureFlag pretenure = NOT_TENURED) {
    Handle<HeapNumber> heap_number = NewHeapNumber(mode, pretenure);
    heap_number->set_value(value);
    return heap_number;
  }
  Handle<HeapNumber> NewHeapNumberFromBits(
      uint64_t bits, MutableMode mode = IMMUTABLE,
      PretenureFlag pretenure = NOT_TENURED) {
    Handle<HeapNumber> heap_number = NewHeapNumber(mode, pretenure);
    heap_number->set_value_as_bits(bits);
    return heap_number;
  }
  // Creates mutable heap number object with value field set to hole NaN.
  Handle<HeapNumber> NewMutableHeapNumber(
      PretenureFlag pretenure = NOT_TENURED) {
    return NewHeapNumberFromBits(kHoleNanInt64, MUTABLE, pretenure);
  }

  // Creates heap number object with not yet set value field.
  Handle<HeapNumber> NewHeapNumber(MutableMode mode,
                                   PretenureFlag pretenure = NOT_TENURED);

#define SIMD128_NEW_DECL(TYPE, Type, type, lane_count, lane_type) \
  Handle<Type> New##Type(lane_type lanes[lane_count],             \
                         PretenureFlag pretenure = NOT_TENURED);
  SIMD128_TYPES(SIMD128_NEW_DECL)
#undef SIMD128_NEW_DECL

  Handle<JSWeakMap> NewJSWeakMap();

  Handle<JSObject> NewArgumentsObject(Handle<JSFunction> callee, int length);

  // JS objects are pretenured when allocated by the bootstrapper and
  // runtime.
  Handle<JSObject> NewJSObject(Handle<JSFunction> constructor,
                               PretenureFlag pretenure = NOT_TENURED);
  // JSObject without a prototype.
  Handle<JSObject> NewJSObjectWithNullProto(
      PretenureFlag pretenure = NOT_TENURED);

  // Global objects are pretenured and initialized based on a constructor.
  Handle<JSGlobalObject> NewJSGlobalObject(Handle<JSFunction> constructor);

  // JS objects are pretenured when allocated by the bootstrapper and
  // runtime.
  Handle<JSObject> NewJSObjectFromMap(
      Handle<Map> map,
      PretenureFlag pretenure = NOT_TENURED,
      Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());

  // JS arrays are pretenured when allocated by the parser.

  // Create a JSArray with a specified length and elements initialized
  // according to the specified mode.
  Handle<JSArray> NewJSArray(
      ElementsKind elements_kind, int length, int capacity,
      ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<JSArray> NewJSArray(
      int capacity, ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
      PretenureFlag pretenure = NOT_TENURED) {
    if (capacity != 0) {
      elements_kind = GetHoleyElementsKind(elements_kind);
    }
    return NewJSArray(elements_kind, 0, capacity,
                      INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, pretenure);
  }

  // Create a JSArray with the given elements.
  Handle<JSArray> NewJSArrayWithElements(Handle<FixedArrayBase> elements,
                                         ElementsKind elements_kind, int length,
                                         PretenureFlag pretenure = NOT_TENURED);

  Handle<JSArray> NewJSArrayWithElements(
      Handle<FixedArrayBase> elements,
      ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
      PretenureFlag pretenure = NOT_TENURED) {
    return NewJSArrayWithElements(elements, elements_kind, elements->length(),
                                  pretenure);
  }

  void NewJSArrayStorage(
      Handle<JSArray> array,
      int length,
      int capacity,
      ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS);

  Handle<JSGeneratorObject> NewJSGeneratorObject(Handle<JSFunction> function);

  Handle<JSModuleNamespace> NewJSModuleNamespace();

  Handle<Module> NewModule(Handle<SharedFunctionInfo> code);

  Handle<JSArrayBuffer> NewJSArrayBuffer(
      SharedFlag shared = SharedFlag::kNotShared,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type,
                                       PretenureFlag pretenure = NOT_TENURED);

  Handle<JSTypedArray> NewJSTypedArray(ElementsKind elements_kind,
                                       PretenureFlag pretenure = NOT_TENURED);

  // Creates a new JSTypedArray with the specified buffer.
  Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type,
                                       Handle<JSArrayBuffer> buffer,
                                       size_t byte_offset, size_t length,
                                       PretenureFlag pretenure = NOT_TENURED);

  // Creates a new on-heap JSTypedArray.
  Handle<JSTypedArray> NewJSTypedArray(ElementsKind elements_kind,
                                       size_t number_of_elements,
                                       PretenureFlag pretenure = NOT_TENURED);

  Handle<JSDataView> NewJSDataView();
  Handle<JSDataView> NewJSDataView(Handle<JSArrayBuffer> buffer,
                                   size_t byte_offset, size_t byte_length);

  Handle<JSIteratorResult> NewJSIteratorResult(Handle<Object> value, bool done);

  Handle<JSMap> NewJSMap();
  Handle<JSSet> NewJSSet();

  // TODO(aandrey): Maybe these should take table, index and kind arguments.
  Handle<JSMapIterator> NewJSMapIterator();
  Handle<JSSetIterator> NewJSSetIterator();

  // Allocates a bound function.
  MaybeHandle<JSBoundFunction> NewJSBoundFunction(
      Handle<JSReceiver> target_function, Handle<Object> bound_this,
      Vector<Handle<Object>> bound_args);

  // Allocates a Harmony proxy.
  Handle<JSProxy> NewJSProxy(Handle<JSReceiver> target,
                             Handle<JSReceiver> handler);

  // Reinitialize an JSGlobalProxy based on a constructor.  The object
  // must have the same size as objects allocated using the
  // constructor.  The object is reinitialized and behaves as an
  // object that has been freshly allocated using the constructor.
  void ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> global,
                                 Handle<JSFunction> constructor);

  Handle<JSGlobalProxy> NewUninitializedJSGlobalProxy(int size);

  Handle<JSFunction> NewFunction(Handle<Map> map,
                                 Handle<SharedFunctionInfo> info,
                                 Handle<Object> context_or_undefined,
                                 PretenureFlag pretenure = TENURED);
  Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
                                 Handle<Object> prototype,
                                 bool is_strict = false);
  Handle<JSFunction> NewFunction(Handle<String> name);
  Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
                                                 Handle<Code> code,
                                                 bool is_strict = false);

  Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
      Handle<Map> initial_map, Handle<SharedFunctionInfo> function_info,
      Handle<Object> context_or_undefined, Handle<Cell> vector,
      PretenureFlag pretenure = TENURED);

  Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
      Handle<SharedFunctionInfo> function_info, Handle<Context> context,
      Handle<Cell> vector, PretenureFlag pretenure = TENURED);

  Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
      Handle<Map> initial_map, Handle<SharedFunctionInfo> function_info,
      Handle<Object> context_or_undefined, PretenureFlag pretenure = TENURED);

  Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
      Handle<SharedFunctionInfo> function_info, Handle<Context> context,
      PretenureFlag pretenure = TENURED);

  Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
                                 Handle<Object> prototype, InstanceType type,
                                 int instance_size,
                                 bool is_strict = false);
  Handle<JSFunction> NewFunction(Handle<String> name,
                                 Handle<Code> code,
                                 InstanceType type,
                                 int instance_size);
  Handle<JSFunction> NewFunction(Handle<Map> map, Handle<String> name,
                                 MaybeHandle<Code> maybe_code);

  // Create a serialized scope info.
  Handle<ScopeInfo> NewScopeInfo(int length);

  Handle<ModuleInfoEntry> NewModuleInfoEntry();
  Handle<ModuleInfo> NewModuleInfo();

  // Create an External object for V8's external API.
  Handle<JSObject> NewExternal(void* value);

  // The reference to the Code object is stored in self_reference.
  // This allows generated code to reference its own Code object
  // by containing this handle.
  Handle<Code> NewCode(const CodeDesc& desc,
                       Code::Flags flags,
                       Handle<Object> self_reference,
                       bool immovable = false,
                       bool crankshafted = false,
                       int prologue_offset = Code::kPrologueOffsetNotSet,
                       bool is_debug = false);

  Handle<Code> CopyCode(Handle<Code> code);

  Handle<BytecodeArray> CopyBytecodeArray(Handle<BytecodeArray>);

  // Interface for creating error objects.
  Handle<Object> NewError(Handle<JSFunction> constructor,
                          Handle<String> message);

  Handle<Object> NewInvalidStringLengthError();

  Handle<Object> NewURIError() {
    return NewError(isolate()->uri_error_function(),
                    MessageTemplate::kURIMalformed);
  }

  Handle<Object> NewError(Handle<JSFunction> constructor,
                          MessageTemplate::Template template_index,
                          Handle<Object> arg0 = Handle<Object>(),
                          Handle<Object> arg1 = Handle<Object>(),
                          Handle<Object> arg2 = Handle<Object>());

#define DECLARE_ERROR(NAME)                                          \
  Handle<Object> New##NAME(MessageTemplate::Template template_index, \
                           Handle<Object> arg0 = Handle<Object>(),   \
                           Handle<Object> arg1 = Handle<Object>(),   \
                           Handle<Object> arg2 = Handle<Object>());
  DECLARE_ERROR(Error)
  DECLARE_ERROR(EvalError)
  DECLARE_ERROR(RangeError)
  DECLARE_ERROR(ReferenceError)
  DECLARE_ERROR(SyntaxError)
  DECLARE_ERROR(TypeError)
  DECLARE_ERROR(WasmCompileError)
  DECLARE_ERROR(WasmLinkError)
  DECLARE_ERROR(WasmRuntimeError)
#undef DECLARE_ERROR

  Handle<String> NumberToString(Handle<Object> number,
                                bool check_number_string_cache = true);

  Handle<String> Uint32ToString(uint32_t value) {
    return NumberToString(NewNumberFromUint(value));
  }

  Handle<JSFunction> InstallMembers(Handle<JSFunction> function);

#define ROOT_ACCESSOR(type, name, camel_name)                         \
  inline Handle<type> name() {                                        \
    return Handle<type>(bit_cast<type**>(                             \
        &isolate()->heap()->roots_[Heap::k##camel_name##RootIndex])); \
  }
  ROOT_LIST(ROOT_ACCESSOR)
#undef ROOT_ACCESSOR

#define STRUCT_MAP_ACCESSOR(NAME, Name, name)                      \
  inline Handle<Map> name##_map() {                                \
    return Handle<Map>(bit_cast<Map**>(                            \
        &isolate()->heap()->roots_[Heap::k##Name##MapRootIndex])); \
  }
  STRUCT_LIST(STRUCT_MAP_ACCESSOR)
#undef STRUCT_MAP_ACCESSOR

#define STRING_ACCESSOR(name, str)                              \
  inline Handle<String> name() {                                \
    return Handle<String>(bit_cast<String**>(                   \
        &isolate()->heap()->roots_[Heap::k##name##RootIndex])); \
  }
  INTERNALIZED_STRING_LIST(STRING_ACCESSOR)
#undef STRING_ACCESSOR

#define SYMBOL_ACCESSOR(name)                                   \
  inline Handle<Symbol> name() {                                \
    return Handle<Symbol>(bit_cast<Symbol**>(                   \
        &isolate()->heap()->roots_[Heap::k##name##RootIndex])); \
  }
  PRIVATE_SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR

#define SYMBOL_ACCESSOR(name, description)                      \
  inline Handle<Symbol> name() {                                \
    return Handle<Symbol>(bit_cast<Symbol**>(                   \
        &isolate()->heap()->roots_[Heap::k##name##RootIndex])); \
  }
  PUBLIC_SYMBOL_LIST(SYMBOL_ACCESSOR)
  WELL_KNOWN_SYMBOL_LIST(SYMBOL_ACCESSOR)
#undef SYMBOL_ACCESSOR

  // Allocates a new SharedFunctionInfo object.
  Handle<SharedFunctionInfo> NewSharedFunctionInfo(
      Handle<String> name, int number_of_literals, FunctionKind kind,
      Handle<Code> code, Handle<ScopeInfo> scope_info);
  Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name,
                                                   MaybeHandle<Code> code,
                                                   bool is_constructor);

  Handle<SharedFunctionInfo> NewSharedFunctionInfoForLiteral(
      FunctionLiteral* literal, Handle<Script> script);

  static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
    return (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
            function_mode == FUNCTION_WITH_READONLY_PROTOTYPE);
  }

  Handle<Map> CreateSloppyFunctionMap(FunctionMode function_mode);

  Handle<Map> CreateStrictFunctionMap(FunctionMode function_mode,
                                      Handle<JSFunction> empty_function);

  Handle<Map> CreateClassFunctionMap(Handle<JSFunction> empty_function);

  // Allocates a new JSMessageObject object.
  Handle<JSMessageObject> NewJSMessageObject(MessageTemplate::Template message,
                                             Handle<Object> argument,
                                             int start_position,
                                             int end_position,
                                             Handle<Object> script,
                                             Handle<Object> stack_frames);

  Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);

  // Return a map for given number of properties using the map cache in the
  // native context.
  Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context,
                                        int number_of_properties,
                                        bool* is_result_from_cache);

  Handle<RegExpMatchInfo> NewRegExpMatchInfo();

  // Creates a new FixedArray that holds the data associated with the
  // atom regexp and stores it in the regexp.
  void SetRegExpAtomData(Handle<JSRegExp> regexp,
                         JSRegExp::Type type,
                         Handle<String> source,
                         JSRegExp::Flags flags,
                         Handle<Object> match_pattern);

  // Creates a new FixedArray that holds the data associated with the
  // irregexp regexp and stores it in the regexp.
  void SetRegExpIrregexpData(Handle<JSRegExp> regexp,
                             JSRegExp::Type type,
                             Handle<String> source,
                             JSRegExp::Flags flags,
                             int capture_count);

  // Returns the value for a known global constant (a property of the global
  // object which is neither configurable nor writable) like 'undefined'.
  // Returns a null handle when the given name is unknown.
  Handle<Object> GlobalConstantFor(Handle<Name> name);

  // Converts the given boolean condition to JavaScript boolean value.
  Handle<Object> ToBoolean(bool value);

  // Converts the given ToPrimitive hint to it's string representation.
  Handle<String> ToPrimitiveHintString(ToPrimitiveHint hint);

 private:
  Isolate* isolate() { return reinterpret_cast<Isolate*>(this); }

  // Creates a heap object based on the map. The fields of the heap object are
  // not initialized by New<>() functions. It's the responsibility of the caller
  // to do that.
  template<typename T>
  Handle<T> New(Handle<Map> map, AllocationSpace space);

  template<typename T>
  Handle<T> New(Handle<Map> map,
                AllocationSpace space,
                Handle<AllocationSite> allocation_site);

  MaybeHandle<String> NewStringFromTwoByte(const uc16* string, int length,
                                           PretenureFlag pretenure);

  // Creates a code object that is not yet fully initialized yet.
  inline Handle<Code> NewCodeRaw(int object_size, bool immovable);

  // Attempt to find the number in a small cache.  If we finds it, return
  // the string representation of the number.  Otherwise return undefined.
  Handle<Object> GetNumberStringCache(Handle<Object> number);

  // Update the cache with a new number-string pair.
  void SetNumberStringCache(Handle<Object> number, Handle<String> string);

  // Create a JSArray with no elements and no length.
  Handle<JSArray> NewJSArray(ElementsKind elements_kind,
                             PretenureFlag pretenure = NOT_TENURED);

  void SetFunctionInstanceDescriptor(Handle<Map> map,
                                     FunctionMode function_mode);

  void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
                                           FunctionMode function_mode);

  void SetClassFunctionInstanceDescriptor(Handle<Map> map);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_FACTORY_H_
