• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);
LookupAsciiSymbol(const char * 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   }
SYMBOL_LIST(SYMBOL_ACCESSOR)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:
isolate()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