Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_FACTORY_H_
     29 #define V8_FACTORY_H_
     30 
     31 #include "globals.h"
     32 #include "handles.h"
     33 #include "heap.h"
     34 
     35 namespace v8 {
     36 namespace internal {
     37 
     38 // Interface for handle based allocation.
     39 
     40 class Factory {
     41  public:
     42   // Allocate a new uninitialized fixed array.
     43   Handle<FixedArray> NewFixedArray(
     44       int size,
     45       PretenureFlag pretenure = NOT_TENURED);
     46 
     47   // Allocate a new fixed array with non-existing entries (the hole).
     48   Handle<FixedArray> NewFixedArrayWithHoles(
     49       int size,
     50       PretenureFlag pretenure = NOT_TENURED);
     51 
     52   // Allocate a new uninitialized fixed double array.
     53   Handle<FixedDoubleArray> NewFixedDoubleArray(
     54       int size,
     55       PretenureFlag pretenure = NOT_TENURED);
     56 
     57   Handle<SeededNumberDictionary> NewSeededNumberDictionary(
     58       int at_least_space_for);
     59 
     60   Handle<UnseededNumberDictionary> NewUnseededNumberDictionary(
     61       int at_least_space_for);
     62 
     63   Handle<StringDictionary> NewStringDictionary(int at_least_space_for);
     64 
     65   Handle<ObjectHashSet> NewObjectHashSet(int at_least_space_for);
     66 
     67   Handle<ObjectHashTable> NewObjectHashTable(int at_least_space_for);
     68 
     69   Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors);
     70   Handle<DeoptimizationInputData> NewDeoptimizationInputData(
     71       int deopt_entry_count,
     72       PretenureFlag pretenure);
     73   Handle<DeoptimizationOutputData> NewDeoptimizationOutputData(
     74       int deopt_entry_count,
     75       PretenureFlag pretenure);
     76   // Allocates a pre-tenured empty AccessorPair.
     77   Handle<AccessorPair> NewAccessorPair();
     78 
     79   Handle<TypeFeedbackInfo> NewTypeFeedbackInfo();
     80 
     81   Handle<String> LookupSymbol(Vector<const char> str);
     82   Handle<String> LookupSymbol(Handle<String> str);
     83   Handle<String> LookupAsciiSymbol(Vector<const char> str);
     84   Handle<String> LookupAsciiSymbol(Handle<SeqAsciiString>,
     85                                    int from,
     86                                    int length);
     87   Handle<String> LookupTwoByteSymbol(Vector<const uc16> str);
     88   Handle<String> LookupAsciiSymbol(const char* str) {
     89     return LookupSymbol(CStrVector(str));
     90   }
     91 
     92 
     93   // String creation functions.  Most of the string creation functions take
     94   // a Heap::PretenureFlag argument to optionally request that they be
     95   // allocated in the old generation.  The pretenure flag defaults to
     96   // DONT_TENURE.
     97   //
     98   // Creates a new String object.  There are two String encodings: ASCII and
     99   // two byte.  One should choose between the three string factory functions
    100   // based on the encoding of the string buffer that the string is
    101   // initialized from.
    102   //   - ...FromAscii initializes the string from a buffer that is ASCII
    103   //     encoded (it does not check that the buffer is ASCII encoded) and
    104   //     the result will be ASCII encoded.
    105   //   - ...FromUtf8 initializes the string from a buffer that is UTF-8
    106   //     encoded.  If the characters are all single-byte characters, the
    107   //     result will be ASCII encoded, otherwise it will converted to two
    108   //     byte.
    109   //   - ...FromTwoByte initializes the string from a buffer that is two
    110   //     byte encoded.  If the characters are all single-byte characters,
    111   //     the result will be converted to ASCII, otherwise it will be left as
    112   //     two byte.
    113   //
    114   // ASCII strings are pretenured when used as keys in the SourceCodeCache.
    115   Handle<String> NewStringFromAscii(
    116       Vector<const char> str,
    117       PretenureFlag pretenure = NOT_TENURED);
    118 
    119   // UTF8 strings are pretenured when used for regexp literal patterns and
    120   // flags in the parser.
    121   Handle<String> NewStringFromUtf8(
    122       Vector<const char> str,
    123       PretenureFlag pretenure = NOT_TENURED);
    124 
    125   Handle<String> NewStringFromTwoByte(
    126       Vector<const uc16> str,
    127       PretenureFlag pretenure = NOT_TENURED);
    128 
    129   // Allocates and partially initializes an ASCII or TwoByte String. The
    130   // characters of the string are uninitialized. Currently used in regexp code
    131   // only, where they are pretenured.
    132   Handle<SeqAsciiString> NewRawAsciiString(
    133       int length,
    134       PretenureFlag pretenure = NOT_TENURED);
    135   Handle<SeqTwoByteString> NewRawTwoByteString(
    136       int length,
    137       PretenureFlag pretenure = NOT_TENURED);
    138 
    139   // Create a new cons string object which consists of a pair of strings.
    140   Handle<String> NewConsString(Handle<String> first,
    141                                Handle<String> second);
    142 
    143   // Create a new string object which holds a substring of a string.
    144   Handle<String> NewSubString(Handle<String> str,
    145                               int begin,
    146                               int end);
    147 
    148   // Create a new string object which holds a proper substring of a string.
    149   Handle<String> NewProperSubString(Handle<String> str,
    150                                     int begin,
    151                                     int end);
    152 
    153   // Creates a new external String object.  There are two String encodings
    154   // in the system: ASCII and two byte.  Unlike other String types, it does
    155   // not make sense to have a UTF-8 factory function for external strings,
    156   // because we cannot change the underlying buffer.
    157   Handle<String> NewExternalStringFromAscii(
    158       const ExternalAsciiString::Resource* resource);
    159   Handle<String> NewExternalStringFromTwoByte(
    160       const ExternalTwoByteString::Resource* resource);
    161 
    162   // Create a global (but otherwise uninitialized) context.
    163   Handle<Context> NewGlobalContext();
    164 
    165   // Create a function context.
    166   Handle<Context> NewFunctionContext(int length,
    167                                      Handle<JSFunction> function);
    168 
    169   // Create a catch context.
    170   Handle<Context> NewCatchContext(Handle<JSFunction> function,
    171                                   Handle<Context> previous,
    172                                   Handle<String> name,
    173                                   Handle<Object> thrown_object);
    174 
    175   // Create a 'with' context.
    176   Handle<Context> NewWithContext(Handle<JSFunction> function,
    177                                  Handle<Context> previous,
    178                                  Handle<JSObject> extension);
    179 
    180   // Create a 'block' context.
    181   Handle<Context> NewBlockContext(Handle<JSFunction> function,
    182                                   Handle<Context> previous,
    183                                   Handle<ScopeInfo> scope_info);
    184 
    185   // Return the Symbol matching the passed in string.
    186   Handle<String> SymbolFromString(Handle<String> value);
    187 
    188   // Allocate a new struct.  The struct is pretenured (allocated directly in
    189   // the old generation).
    190   Handle<Struct> NewStruct(InstanceType type);
    191 
    192   Handle<AccessorInfo> NewAccessorInfo();
    193 
    194   Handle<Script> NewScript(Handle<String> source);
    195 
    196   // Foreign objects are pretenured when allocated by the bootstrapper.
    197   Handle<Foreign> NewForeign(Address addr,
    198                              PretenureFlag pretenure = NOT_TENURED);
    199 
    200   // Allocate a new foreign object.  The foreign is pretenured (allocated
    201   // directly in the old generation).
    202   Handle<Foreign> NewForeign(const AccessorDescriptor* foreign);
    203 
    204   Handle<ByteArray> NewByteArray(int length,
    205                                  PretenureFlag pretenure = NOT_TENURED);
    206 
    207   Handle<ExternalArray> NewExternalArray(
    208       int length,
    209       ExternalArrayType array_type,
    210       void* external_pointer,
    211       PretenureFlag pretenure = NOT_TENURED);
    212 
    213   Handle<JSGlobalPropertyCell> NewJSGlobalPropertyCell(
    214       Handle<Object> value);
    215 
    216   Handle<Map> NewMap(InstanceType type,
    217                      int instance_size,
    218                      ElementsKind elements_kind = FAST_ELEMENTS);
    219 
    220   Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function);
    221 
    222   Handle<Map> CopyMapDropDescriptors(Handle<Map> map);
    223 
    224   // Copy the map adding more inobject properties if possible without
    225   // overflowing the instance size.
    226   Handle<Map> CopyMap(Handle<Map> map, int extra_inobject_props);
    227 
    228   Handle<Map> CopyMapDropTransitions(Handle<Map> map);
    229 
    230   Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
    231                                        ElementsKind elements_kind);
    232 
    233   Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
    234 
    235   Handle<FixedDoubleArray> CopyFixedDoubleArray(
    236       Handle<FixedDoubleArray> array);
    237 
    238   // Numbers (e.g. literals) are pretenured by the parser.
    239   Handle<Object> NewNumber(double value,
    240                            PretenureFlag pretenure = NOT_TENURED);
    241 
    242   Handle<Object> NewNumberFromInt(int32_t value,
    243                                   PretenureFlag pretenure = NOT_TENURED);
    244   Handle<Object> NewNumberFromUint(uint32_t value,
    245                                   PretenureFlag pretenure = NOT_TENURED);
    246 
    247   // These objects are used by the api to create env-independent data
    248   // structures in the heap.
    249   Handle<JSObject> NewNeanderObject();
    250 
    251   Handle<JSObject> NewArgumentsObject(Handle<Object> callee, int length);
    252 
    253   // JS objects are pretenured when allocated by the bootstrapper and
    254   // runtime.
    255   Handle<JSObject> NewJSObject(Handle<JSFunction> constructor,
    256                                PretenureFlag pretenure = NOT_TENURED);
    257 
    258   // Global objects are pretenured.
    259   Handle<GlobalObject> NewGlobalObject(Handle<JSFunction> constructor);
    260 
    261   // JS objects are pretenured when allocated by the bootstrapper and
    262   // runtime.
    263   Handle<JSObject> NewJSObjectFromMap(Handle<Map> map);
    264 
    265   // JS arrays are pretenured when allocated by the parser.
    266   Handle<JSArray> NewJSArray(int capacity,
    267                              ElementsKind elements_kind = FAST_ELEMENTS,
    268                              PretenureFlag pretenure = NOT_TENURED);
    269 
    270   Handle<JSArray> NewJSArrayWithElements(
    271       Handle<FixedArrayBase> elements,
    272       ElementsKind elements_kind = FAST_ELEMENTS,
    273       PretenureFlag pretenure = NOT_TENURED);
    274 
    275   void SetElementsCapacityAndLength(Handle<JSArray> array,
    276                                     int capacity,
    277                                     int length);
    278 
    279   void SetContent(Handle<JSArray> array, Handle<FixedArrayBase> elements);
    280 
    281   void EnsureCanContainHeapObjectElements(Handle<JSArray> array);
    282   void EnsureCanContainElements(Handle<JSArray> array,
    283                                 Handle<FixedArrayBase> elements,
    284                                 EnsureElementsMode mode);
    285 
    286   Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);
    287 
    288   // Change the type of the argument into a JS object/function and reinitialize.
    289   void BecomeJSObject(Handle<JSReceiver> object);
    290   void BecomeJSFunction(Handle<JSReceiver> object);
    291 
    292   void SetIdentityHash(Handle<JSObject> object, Object* hash);
    293 
    294   Handle<JSFunction> NewFunction(Handle<String> name,
    295                                  Handle<Object> prototype);
    296 
    297   Handle<JSFunction> NewFunctionWithoutPrototype(
    298       Handle<String> name,
    299       LanguageMode language_mode);
    300 
    301   Handle<JSFunction> NewFunction(Handle<Object> super, bool is_global);
    302 
    303   Handle<JSFunction> BaseNewFunctionFromSharedFunctionInfo(
    304       Handle<SharedFunctionInfo> function_info,
    305       Handle<Map> function_map,
    306       PretenureFlag pretenure);
    307 
    308   Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
    309       Handle<SharedFunctionInfo> function_info,
    310       Handle<Context> context,
    311       PretenureFlag pretenure = TENURED);
    312 
    313   Handle<ScopeInfo> NewScopeInfo(int length);
    314 
    315   Handle<Code> NewCode(const CodeDesc& desc,
    316                        Code::Flags flags,
    317                        Handle<Object> self_reference,
    318                        bool immovable = false);
    319 
    320   Handle<Code> CopyCode(Handle<Code> code);
    321 
    322   Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info);
    323 
    324   Handle<Object> ToObject(Handle<Object> object);
    325   Handle<Object> ToObject(Handle<Object> object,
    326                           Handle<Context> global_context);
    327 
    328   // Interface for creating error objects.
    329 
    330   Handle<Object> NewError(const char* maker, const char* type,
    331                           Handle<JSArray> args);
    332   Handle<Object> NewError(const char* maker, const char* type,
    333                           Vector< Handle<Object> > args);
    334   Handle<Object> NewError(const char* type,
    335                           Vector< Handle<Object> > args);
    336   Handle<Object> NewError(Handle<String> message);
    337   Handle<Object> NewError(const char* constructor,
    338                           Handle<String> message);
    339 
    340   Handle<Object> NewTypeError(const char* type,
    341                               Vector< Handle<Object> > args);
    342   Handle<Object> NewTypeError(Handle<String> message);
    343 
    344   Handle<Object> NewRangeError(const char* type,
    345                                Vector< Handle<Object> > args);
    346   Handle<Object> NewRangeError(Handle<String> message);
    347 
    348   Handle<Object> NewSyntaxError(const char* type, Handle<JSArray> args);
    349   Handle<Object> NewSyntaxError(Handle<String> message);
    350 
    351   Handle<Object> NewReferenceError(const char* type,
    352                                    Vector< Handle<Object> > args);
    353   Handle<Object> NewReferenceError(Handle<String> message);
    354 
    355   Handle<Object> NewEvalError(const char* type,
    356                               Vector< Handle<Object> > args);
    357 
    358 
    359   Handle<JSFunction> NewFunction(Handle<String> name,
    360                                  InstanceType type,
    361                                  int instance_size,
    362                                  Handle<Code> code,
    363                                  bool force_initial_map);
    364 
    365   Handle<JSFunction> NewFunction(Handle<Map> function_map,
    366       Handle<SharedFunctionInfo> shared, Handle<Object> prototype);
    367 
    368 
    369   Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name,
    370                                               InstanceType type,
    371                                               int instance_size,
    372                                               Handle<JSObject> prototype,
    373                                               Handle<Code> code,
    374                                               bool force_initial_map);
    375 
    376   Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
    377                                                  Handle<Code> code);
    378 
    379   Handle<DescriptorArray> CopyAppendForeignDescriptor(
    380       Handle<DescriptorArray> array,
    381       Handle<String> key,
    382       Handle<Object> value,
    383       PropertyAttributes attributes);
    384 
    385   Handle<String> NumberToString(Handle<Object> number);
    386   Handle<String> Uint32ToString(uint32_t value);
    387 
    388   enum ApiInstanceType {
    389     JavaScriptObject,
    390     InnerGlobalObject,
    391     OuterGlobalObject
    392   };
    393 
    394   Handle<JSFunction> CreateApiFunction(
    395       Handle<FunctionTemplateInfo> data,
    396       ApiInstanceType type = JavaScriptObject);
    397 
    398   Handle<JSFunction> InstallMembers(Handle<JSFunction> function);
    399 
    400   // Installs interceptors on the instance.  'desc' is a function template,
    401   // and instance is an object instance created by the function of this
    402   // function template.
    403   void ConfigureInstance(Handle<FunctionTemplateInfo> desc,
    404                          Handle<JSObject> instance,
    405                          bool* pending_exception);
    406 
    407 #define ROOT_ACCESSOR(type, name, camel_name)                                  \
    408   inline Handle<type> name() {                                                 \
    409     return Handle<type>(BitCast<type**>(                                       \
    410         &isolate()->heap()->roots_[Heap::k##camel_name##RootIndex]));          \
    411   }
    412   ROOT_LIST(ROOT_ACCESSOR)
    413 #undef ROOT_ACCESSOR_ACCESSOR
    414 
    415 #define SYMBOL_ACCESSOR(name, str)                                             \
    416   inline Handle<String> name() {                                               \
    417     return Handle<String>(BitCast<String**>(                                   \
    418         &isolate()->heap()->roots_[Heap::k##name##RootIndex]));                \
    419   }
    420   SYMBOL_LIST(SYMBOL_ACCESSOR)
    421 #undef SYMBOL_ACCESSOR
    422 
    423   Handle<String> hidden_symbol() {
    424     return Handle<String>(&isolate()->heap()->hidden_symbol_);
    425   }
    426 
    427   Handle<SharedFunctionInfo> NewSharedFunctionInfo(
    428       Handle<String> name,
    429       int number_of_literals,
    430       Handle<Code> code,
    431       Handle<ScopeInfo> scope_info);
    432   Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
    433 
    434   Handle<JSMessageObject> NewJSMessageObject(
    435       Handle<String> type,
    436       Handle<JSArray> arguments,
    437       int start_position,
    438       int end_position,
    439       Handle<Object> script,
    440       Handle<Object> stack_trace,
    441       Handle<Object> stack_frames);
    442 
    443   Handle<SeededNumberDictionary> DictionaryAtNumberPut(
    444       Handle<SeededNumberDictionary>,
    445       uint32_t key,
    446       Handle<Object> value);
    447 
    448   Handle<UnseededNumberDictionary> DictionaryAtNumberPut(
    449       Handle<UnseededNumberDictionary>,
    450       uint32_t key,
    451       Handle<Object> value);
    452 
    453 #ifdef ENABLE_DEBUGGER_SUPPORT
    454   Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
    455 #endif
    456 
    457   // Return a map using the map cache in the global context.
    458   // The key the an ordered set of property names.
    459   Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context,
    460                                         Handle<FixedArray> keys);
    461 
    462   // Creates a new FixedArray that holds the data associated with the
    463   // atom regexp and stores it in the regexp.
    464   void SetRegExpAtomData(Handle<JSRegExp> regexp,
    465                          JSRegExp::Type type,
    466                          Handle<String> source,
    467                          JSRegExp::Flags flags,
    468                          Handle<Object> match_pattern);
    469 
    470   // Creates a new FixedArray that holds the data associated with the
    471   // irregexp regexp and stores it in the regexp.
    472   void SetRegExpIrregexpData(Handle<JSRegExp> regexp,
    473                              JSRegExp::Type type,
    474                              Handle<String> source,
    475                              JSRegExp::Flags flags,
    476                              int capture_count);
    477 
    478   // Returns the value for a known global constant (a property of the global
    479   // object which is neither configurable nor writable) like 'undefined'.
    480   // Returns a null handle when the given name is unknown.
    481   Handle<Object> GlobalConstantFor(Handle<String> name);
    482 
    483   // Converts the given boolean condition to JavaScript boolean value.
    484   Handle<Object> ToBoolean(bool value);
    485 
    486  private:
    487   Isolate* isolate() { return reinterpret_cast<Isolate*>(this); }
    488 
    489   Handle<JSFunction> NewFunctionHelper(Handle<String> name,
    490                                        Handle<Object> prototype);
    491 
    492   Handle<JSFunction> NewFunctionWithoutPrototypeHelper(
    493       Handle<String> name,
    494       LanguageMode language_mode);
    495 
    496   Handle<DescriptorArray> CopyAppendCallbackDescriptors(
    497       Handle<DescriptorArray> array,
    498       Handle<Object> descriptors);
    499 
    500   // Create a new map cache.
    501   Handle<MapCache> NewMapCache(int at_least_space_for);
    502 
    503   // Update the map cache in the global context with (keys, map)
    504   Handle<MapCache> AddToMapCache(Handle<Context> context,
    505                                  Handle<FixedArray> keys,
    506                                  Handle<Map> map);
    507 };
    508 
    509 
    510 } }  // namespace v8::internal
    511 
    512 #endif  // V8_FACTORY_H_
    513