// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef V8_FACTORY_H_
#define V8_FACTORY_H_

#include "globals.h"
#include "handles.h"
#include "heap.h"

namespace v8 {
namespace internal {

// Interface for handle based allocation.

class Factory {
 public:
  // Allocate a new uninitialized fixed array.
  Handle<FixedArray> NewFixedArray(
      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);

  // Allocate a new uninitialized fixed double array.
  Handle<FixedDoubleArray> NewFixedDoubleArray(
      int size,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<SeededNumberDictionary> NewSeededNumberDictionary(
      int at_least_space_for);

  Handle<UnseededNumberDictionary> NewUnseededNumberDictionary(
      int at_least_space_for);

  Handle<StringDictionary> NewStringDictionary(int at_least_space_for);

  Handle<ObjectHashSet> NewObjectHashSet(int at_least_space_for);

  Handle<ObjectHashTable> NewObjectHashTable(int at_least_space_for);

  Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors,
                                             int slack = 0);
  Handle<DeoptimizationInputData> NewDeoptimizationInputData(
      int deopt_entry_count,
      PretenureFlag pretenure);
  Handle<DeoptimizationOutputData> NewDeoptimizationOutputData(
      int deopt_entry_count,
      PretenureFlag pretenure);
  // Allocates a pre-tenured empty AccessorPair.
  Handle<AccessorPair> NewAccessorPair();

  Handle<TypeFeedbackInfo> NewTypeFeedbackInfo();

  Handle<String> LookupSymbol(Vector<const char> str);
  Handle<String> LookupSymbol(Handle<String> str);
  Handle<String> LookupAsciiSymbol(Vector<const char> str);
  Handle<String> LookupAsciiSymbol(Handle<SeqAsciiString>,
                                   int from,
                                   int length);
  Handle<String> LookupTwoByteSymbol(Vector<const uc16> str);
  Handle<String> LookupAsciiSymbol(const char* str) {
    return LookupSymbol(CStrVector(str));
  }


  // 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: ASCII 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.
  //   - ...FromAscii initializes the string from a buffer that is ASCII
  //     encoded (it does not check that the buffer is ASCII encoded) and
  //     the result will be ASCII encoded.
  //   - ...FromUtf8 initializes the string from a buffer that is UTF-8
  //     encoded.  If the characters are all single-byte characters, the
  //     result will be ASCII 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 single-byte characters,
  //     the result will be converted to ASCII, otherwise it will be left as
  //     two byte.
  //
  // ASCII strings are pretenured when used as keys in the SourceCodeCache.
  Handle<String> NewStringFromAscii(
      Vector<const char> str,
      PretenureFlag pretenure = NOT_TENURED);

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

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

  // Allocates and partially initializes an ASCII or TwoByte String. The
  // characters of the string are uninitialized. Currently used in regexp code
  // only, where they are pretenured.
  Handle<SeqAsciiString> NewRawAsciiString(
      int length,
      PretenureFlag pretenure = NOT_TENURED);
  Handle<SeqTwoByteString> NewRawTwoByteString(
      int length,
      PretenureFlag pretenure = NOT_TENURED);

  // Create a new cons string object which consists of a pair of strings.
  Handle<String> NewConsString(Handle<String> first,
                               Handle<String> second);

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

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

  // Creates a new external String object.  There are two String encodings
  // in the system: ASCII 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.
  Handle<String> NewExternalStringFromAscii(
      const ExternalAsciiString::Resource* resource);
  Handle<String> NewExternalStringFromTwoByte(
      const ExternalTwoByteString::Resource* resource);

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

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

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

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

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

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

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

  // Return the Symbol matching the passed in string.
  Handle<String> SymbolFromString(Handle<String> value);

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

  Handle<AccessorInfo> NewAccessorInfo();

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

  // 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<ExternalArray> NewExternalArray(
      int length,
      ExternalArrayType array_type,
      void* external_pointer,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<JSGlobalPropertyCell> NewJSGlobalPropertyCell(
      Handle<Object> value);

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

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

  Handle<Map> CopyWithPreallocatedFieldDescriptors(Handle<Map> map);

  // Copy the map adding more inobject properties if possible without
  // overflowing the instance size.
  Handle<Map> CopyMap(Handle<Map> map, int extra_inobject_props);
  Handle<Map> CopyMap(Handle<Map> map);

  Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
                                       ElementsKind elements_kind);

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

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

  // Numbers (e.g. literals) are pretenured by the parser.
  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);

  // These objects are used by the api to create env-independent data
  // structures in the heap.
  Handle<JSObject> NewNeanderObject();

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

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

  // Global objects are pretenured.
  Handle<GlobalObject> NewGlobalObject(Handle<JSFunction> constructor);

  // JS objects are pretenured when allocated by the bootstrapper and
  // runtime.
  Handle<JSObject> NewJSObjectFromMap(Handle<Map> map);

  // JS modules are pretenured.
  Handle<JSModule> NewJSModule(Handle<Context> context,
                               Handle<ScopeInfo> scope_info);

  // JS arrays are pretenured when allocated by the parser.
  Handle<JSArray> NewJSArray(
      int capacity,
      ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
      PretenureFlag pretenure = NOT_TENURED);

  Handle<JSArray> NewJSArrayWithElements(
      Handle<FixedArrayBase> elements,
      ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
      PretenureFlag pretenure = NOT_TENURED);

  void SetElementsCapacityAndLength(Handle<JSArray> array,
                                    int capacity,
                                    int length);

  void SetContent(Handle<JSArray> array, Handle<FixedArrayBase> elements);

  void EnsureCanContainHeapObjectElements(Handle<JSArray> array);
  void EnsureCanContainElements(Handle<JSArray> array,
                                Handle<FixedArrayBase> elements,
                                uint32_t length,
                                EnsureElementsMode mode);

  Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);

  // Change the type of the argument into a JS object/function and reinitialize.
  void BecomeJSObject(Handle<JSReceiver> object);
  void BecomeJSFunction(Handle<JSReceiver> object);

  void SetIdentityHash(Handle<JSObject> object, Smi* hash);

  Handle<JSFunction> NewFunction(Handle<String> name,
                                 Handle<Object> prototype);

  Handle<JSFunction> NewFunctionWithoutPrototype(
      Handle<String> name,
      LanguageMode language_mode);

  Handle<JSFunction> NewFunction(Handle<Object> super, bool is_global);

  Handle<JSFunction> BaseNewFunctionFromSharedFunctionInfo(
      Handle<SharedFunctionInfo> function_info,
      Handle<Map> function_map,
      PretenureFlag pretenure);

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

  Handle<ScopeInfo> NewScopeInfo(int length);

  Handle<Code> NewCode(const CodeDesc& desc,
                       Code::Flags flags,
                       Handle<Object> self_reference,
                       bool immovable = false);

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

  Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info);

  Handle<Object> ToObject(Handle<Object> object);
  Handle<Object> ToObject(Handle<Object> object,
                          Handle<Context> native_context);

  // Interface for creating error objects.

  Handle<Object> NewError(const char* maker, const char* type,
                          Handle<JSArray> args);
  Handle<String> EmergencyNewError(const char* type, Handle<JSArray> args);
  Handle<Object> NewError(const char* maker, const char* type,
                          Vector< Handle<Object> > args);
  Handle<Object> NewError(const char* type,
                          Vector< Handle<Object> > args);
  Handle<Object> NewError(Handle<String> message);
  Handle<Object> NewError(const char* constructor,
                          Handle<String> message);

  Handle<Object> NewTypeError(const char* type,
                              Vector< Handle<Object> > args);
  Handle<Object> NewTypeError(Handle<String> message);

  Handle<Object> NewRangeError(const char* type,
                               Vector< Handle<Object> > args);
  Handle<Object> NewRangeError(Handle<String> message);

  Handle<Object> NewSyntaxError(const char* type, Handle<JSArray> args);
  Handle<Object> NewSyntaxError(Handle<String> message);

  Handle<Object> NewReferenceError(const char* type,
                                   Vector< Handle<Object> > args);
  Handle<Object> NewReferenceError(Handle<String> message);

  Handle<Object> NewEvalError(const char* type,
                              Vector< Handle<Object> > args);


  Handle<JSFunction> NewFunction(Handle<String> name,
                                 InstanceType type,
                                 int instance_size,
                                 Handle<Code> code,
                                 bool force_initial_map);

  Handle<JSFunction> NewFunction(Handle<Map> function_map,
      Handle<SharedFunctionInfo> shared, Handle<Object> prototype);


  Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name,
                                              InstanceType type,
                                              int instance_size,
                                              Handle<JSObject> prototype,
                                              Handle<Code> code,
                                              bool force_initial_map);

  Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
                                                 Handle<Code> code);

  Handle<String> NumberToString(Handle<Object> number);
  Handle<String> Uint32ToString(uint32_t value);

  enum ApiInstanceType {
    JavaScriptObject,
    InnerGlobalObject,
    OuterGlobalObject
  };

  Handle<JSFunction> CreateApiFunction(
      Handle<FunctionTemplateInfo> data,
      ApiInstanceType type = JavaScriptObject);

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

  // Installs interceptors on the instance.  'desc' is a function template,
  // and instance is an object instance created by the function of this
  // function template.
  void ConfigureInstance(Handle<FunctionTemplateInfo> desc,
                         Handle<JSObject> instance,
                         bool* pending_exception);

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

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

  Handle<String> hidden_symbol() {
    return Handle<String>(&isolate()->heap()->hidden_symbol_);
  }

  Handle<SharedFunctionInfo> NewSharedFunctionInfo(
      Handle<String> name,
      int number_of_literals,
      Handle<Code> code,
      Handle<ScopeInfo> scope_info);
  Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);

  Handle<JSMessageObject> NewJSMessageObject(
      Handle<String> type,
      Handle<JSArray> arguments,
      int start_position,
      int end_position,
      Handle<Object> script,
      Handle<Object> stack_trace,
      Handle<Object> stack_frames);

  Handle<SeededNumberDictionary> DictionaryAtNumberPut(
      Handle<SeededNumberDictionary>,
      uint32_t key,
      Handle<Object> value);

  Handle<UnseededNumberDictionary> DictionaryAtNumberPut(
      Handle<UnseededNumberDictionary>,
      uint32_t key,
      Handle<Object> value);

#ifdef ENABLE_DEBUGGER_SUPPORT
  Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
#endif

  // Return a map using the map cache in the native context.
  // The key the an ordered set of property names.
  Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context,
                                        Handle<FixedArray> keys);

  // 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<String> name);

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

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

  Handle<JSFunction> NewFunctionHelper(Handle<String> name,
                                       Handle<Object> prototype);

  Handle<JSFunction> NewFunctionWithoutPrototypeHelper(
      Handle<String> name,
      LanguageMode language_mode);

  // Create a new map cache.
  Handle<MapCache> NewMapCache(int at_least_space_for);

  // Update the map cache in the native context with (keys, map)
  Handle<MapCache> AddToMapCache(Handle<Context> context,
                                 Handle<FixedArray> keys,
                                 Handle<Map> map);
};


} }  // namespace v8::internal

#endif  // V8_FACTORY_H_
