factory.h revision 85b71799222b55eb5dd74ea26efe0c64ab655c8c
1// Copyright 2011 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
35namespace v8 {
36namespace internal {
37
38// Interface for handle based allocation.
39
40class 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<FixedArray> 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<ObjectHashTable> NewObjectHashTable(int at_least_space_for);
66
67  Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors);
68  Handle<DeoptimizationInputData> NewDeoptimizationInputData(
69      int deopt_entry_count,
70      PretenureFlag pretenure);
71  Handle<DeoptimizationOutputData> NewDeoptimizationOutputData(
72      int deopt_entry_count,
73      PretenureFlag pretenure);
74
75  Handle<String> LookupSymbol(Vector<const char> str);
76  Handle<String> LookupSymbol(Handle<String> str);
77  Handle<String> LookupAsciiSymbol(Vector<const char> str);
78  Handle<String> LookupAsciiSymbol(Handle<SeqAsciiString>,
79                                   int from,
80                                   int length);
81  Handle<String> LookupTwoByteSymbol(Vector<const uc16> str);
82  Handle<String> LookupAsciiSymbol(const char* str) {
83    return LookupSymbol(CStrVector(str));
84  }
85
86
87  // String creation functions.  Most of the string creation functions take
88  // a Heap::PretenureFlag argument to optionally request that they be
89  // allocated in the old generation.  The pretenure flag defaults to
90  // DONT_TENURE.
91  //
92  // Creates a new String object.  There are two String encodings: ASCII and
93  // two byte.  One should choose between the three string factory functions
94  // based on the encoding of the string buffer that the string is
95  // initialized from.
96  //   - ...FromAscii initializes the string from a buffer that is ASCII
97  //     encoded (it does not check that the buffer is ASCII encoded) and
98  //     the result will be ASCII encoded.
99  //   - ...FromUtf8 initializes the string from a buffer that is UTF-8
100  //     encoded.  If the characters are all single-byte characters, the
101  //     result will be ASCII encoded, otherwise it will converted to two
102  //     byte.
103  //   - ...FromTwoByte initializes the string from a buffer that is two
104  //     byte encoded.  If the characters are all single-byte characters,
105  //     the result will be converted to ASCII, otherwise it will be left as
106  //     two byte.
107  //
108  // ASCII strings are pretenured when used as keys in the SourceCodeCache.
109  Handle<String> NewStringFromAscii(
110      Vector<const char> str,
111      PretenureFlag pretenure = NOT_TENURED);
112
113  // UTF8 strings are pretenured when used for regexp literal patterns and
114  // flags in the parser.
115  Handle<String> NewStringFromUtf8(
116      Vector<const char> str,
117      PretenureFlag pretenure = NOT_TENURED);
118
119  Handle<String> NewStringFromTwoByte(
120      Vector<const uc16> str,
121      PretenureFlag pretenure = NOT_TENURED);
122
123  // Allocates and partially initializes an ASCII or TwoByte String. The
124  // characters of the string are uninitialized. Currently used in regexp code
125  // only, where they are pretenured.
126  Handle<SeqAsciiString> NewRawAsciiString(
127      int length,
128      PretenureFlag pretenure = NOT_TENURED);
129  Handle<SeqTwoByteString> NewRawTwoByteString(
130      int length,
131      PretenureFlag pretenure = NOT_TENURED);
132
133  // Create a new cons string object which consists of a pair of strings.
134  Handle<String> NewConsString(Handle<String> first,
135                               Handle<String> second);
136
137  // Create a new string object which holds a substring of a string.
138  Handle<String> NewSubString(Handle<String> str,
139                              int begin,
140                              int end);
141
142  // Create a new string object which holds a proper substring of a string.
143  Handle<String> NewProperSubString(Handle<String> str,
144                                    int begin,
145                                    int end);
146
147  // Creates a new external String object.  There are two String encodings
148  // in the system: ASCII and two byte.  Unlike other String types, it does
149  // not make sense to have a UTF-8 factory function for external strings,
150  // because we cannot change the underlying buffer.
151  Handle<String> NewExternalStringFromAscii(
152      ExternalAsciiString::Resource* resource);
153  Handle<String> NewExternalStringFromTwoByte(
154      ExternalTwoByteString::Resource* resource);
155
156  // Create a global (but otherwise uninitialized) context.
157  Handle<Context> NewGlobalContext();
158
159  // Create a function context.
160  Handle<Context> NewFunctionContext(int length,
161                                     Handle<JSFunction> function);
162
163  // Create a catch context.
164  Handle<Context> NewCatchContext(Handle<JSFunction> function,
165                                  Handle<Context> previous,
166                                  Handle<String> name,
167                                  Handle<Object> thrown_object);
168
169  // Create a 'with' context.
170  Handle<Context> NewWithContext(Handle<JSFunction> function,
171                                 Handle<Context> previous,
172                                 Handle<JSObject> extension);
173
174  // Create a 'block' context.
175  Handle<Context> NewBlockContext(Handle<JSFunction> function,
176                                  Handle<Context> previous,
177                                  Handle<SerializedScopeInfo> scope_info);
178
179  // Return the Symbol matching the passed in string.
180  Handle<String> SymbolFromString(Handle<String> value);
181
182  // Allocate a new struct.  The struct is pretenured (allocated directly in
183  // the old generation).
184  Handle<Struct> NewStruct(InstanceType type);
185
186  Handle<AccessorInfo> NewAccessorInfo();
187
188  Handle<Script> NewScript(Handle<String> source);
189
190  // Foreign objects are pretenured when allocated by the bootstrapper.
191  Handle<Foreign> NewForeign(Address addr,
192                             PretenureFlag pretenure = NOT_TENURED);
193
194  // Allocate a new foreign object.  The foreign is pretenured (allocated
195  // directly in the old generation).
196  Handle<Foreign> NewForeign(const AccessorDescriptor* foreign);
197
198  Handle<ByteArray> NewByteArray(int length,
199                                 PretenureFlag pretenure = NOT_TENURED);
200
201  Handle<ExternalArray> NewExternalArray(
202      int length,
203      ExternalArrayType array_type,
204      void* external_pointer,
205      PretenureFlag pretenure = NOT_TENURED);
206
207  Handle<JSGlobalPropertyCell> NewJSGlobalPropertyCell(
208      Handle<Object> value);
209
210  Handle<Map> NewMap(InstanceType type, int instance_size);
211
212  Handle<JSObject> NewFunctionPrototype(Handle<JSFunction> function);
213
214  Handle<Map> CopyMapDropDescriptors(Handle<Map> map);
215
216  // Copy the map adding more inobject properties if possible without
217  // overflowing the instance size.
218  Handle<Map> CopyMap(Handle<Map> map, int extra_inobject_props);
219
220  Handle<Map> CopyMapDropTransitions(Handle<Map> map);
221
222  Handle<Map> GetFastElementsMap(Handle<Map> map);
223
224  Handle<Map> GetSlowElementsMap(Handle<Map> map);
225
226  Handle<Map> GetElementsTransitionMap(Handle<Map> map,
227                                       ElementsKind elements_kind,
228                                       bool safe_to_add_transition);
229
230  Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
231
232  // Numbers (eg, literals) are pretenured by the parser.
233  Handle<Object> NewNumber(double value,
234                           PretenureFlag pretenure = NOT_TENURED);
235
236  Handle<Object> NewNumberFromInt(int value);
237  Handle<Object> NewNumberFromUint(uint32_t value);
238
239  // These objects are used by the api to create env-independent data
240  // structures in the heap.
241  Handle<JSObject> NewNeanderObject();
242
243  Handle<JSObject> NewArgumentsObject(Handle<Object> callee, int length);
244
245  // JS objects are pretenured when allocated by the bootstrapper and
246  // runtime.
247  Handle<JSObject> NewJSObject(Handle<JSFunction> constructor,
248                               PretenureFlag pretenure = NOT_TENURED);
249
250  // Global objects are pretenured.
251  Handle<GlobalObject> NewGlobalObject(Handle<JSFunction> constructor);
252
253  // JS objects are pretenured when allocated by the bootstrapper and
254  // runtime.
255  Handle<JSObject> NewJSObjectFromMap(Handle<Map> map);
256
257  // JS arrays are pretenured when allocated by the parser.
258  Handle<JSArray> NewJSArray(int capacity,
259                             PretenureFlag pretenure = NOT_TENURED);
260
261  Handle<JSArray> NewJSArrayWithElements(
262      Handle<FixedArray> elements,
263      PretenureFlag pretenure = NOT_TENURED);
264
265  Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);
266
267  // Change the type of the argument into a JS object/function and reinitialize.
268  void BecomeJSObject(Handle<JSReceiver> object);
269  void BecomeJSFunction(Handle<JSReceiver> object);
270
271  Handle<JSFunction> NewFunction(Handle<String> name,
272                                 Handle<Object> prototype);
273
274  Handle<JSFunction> NewFunctionWithoutPrototype(
275      Handle<String> name,
276      StrictModeFlag strict_mode);
277
278  Handle<JSFunction> NewFunction(Handle<Object> super, bool is_global);
279
280  Handle<JSFunction> BaseNewFunctionFromSharedFunctionInfo(
281      Handle<SharedFunctionInfo> function_info,
282      Handle<Map> function_map,
283      PretenureFlag pretenure);
284
285  Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
286      Handle<SharedFunctionInfo> function_info,
287      Handle<Context> context,
288      PretenureFlag pretenure = TENURED);
289
290  Handle<SerializedScopeInfo> NewSerializedScopeInfo(int length);
291
292  Handle<Code> NewCode(const CodeDesc& desc,
293                       Code::Flags flags,
294                       Handle<Object> self_reference,
295                       bool immovable = false);
296
297  Handle<Code> CopyCode(Handle<Code> code);
298
299  Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info);
300
301  Handle<Object> ToObject(Handle<Object> object);
302  Handle<Object> ToObject(Handle<Object> object,
303                          Handle<Context> global_context);
304
305  // Interface for creating error objects.
306
307  Handle<Object> NewError(const char* maker, const char* type,
308                          Handle<JSArray> args);
309  Handle<Object> NewError(const char* maker, const char* type,
310                          Vector< Handle<Object> > args);
311  Handle<Object> NewError(const char* type,
312                          Vector< Handle<Object> > args);
313  Handle<Object> NewError(Handle<String> message);
314  Handle<Object> NewError(const char* constructor,
315                          Handle<String> message);
316
317  Handle<Object> NewTypeError(const char* type,
318                              Vector< Handle<Object> > args);
319  Handle<Object> NewTypeError(Handle<String> message);
320
321  Handle<Object> NewRangeError(const char* type,
322                               Vector< Handle<Object> > args);
323  Handle<Object> NewRangeError(Handle<String> message);
324
325  Handle<Object> NewSyntaxError(const char* type, Handle<JSArray> args);
326  Handle<Object> NewSyntaxError(Handle<String> message);
327
328  Handle<Object> NewReferenceError(const char* type,
329                                   Vector< Handle<Object> > args);
330  Handle<Object> NewReferenceError(Handle<String> message);
331
332  Handle<Object> NewEvalError(const char* type,
333                              Vector< Handle<Object> > args);
334
335
336  Handle<JSFunction> NewFunction(Handle<String> name,
337                                 InstanceType type,
338                                 int instance_size,
339                                 Handle<Code> code,
340                                 bool force_initial_map);
341
342  Handle<JSFunction> NewFunction(Handle<Map> function_map,
343      Handle<SharedFunctionInfo> shared, Handle<Object> prototype);
344
345
346  Handle<JSFunction> NewFunctionWithPrototype(Handle<String> name,
347                                              InstanceType type,
348                                              int instance_size,
349                                              Handle<JSObject> prototype,
350                                              Handle<Code> code,
351                                              bool force_initial_map);
352
353  Handle<JSFunction> NewFunctionWithoutPrototype(Handle<String> name,
354                                                 Handle<Code> code);
355
356  Handle<DescriptorArray> CopyAppendForeignDescriptor(
357      Handle<DescriptorArray> array,
358      Handle<String> key,
359      Handle<Object> value,
360      PropertyAttributes attributes);
361
362  Handle<String> NumberToString(Handle<Object> number);
363
364  enum ApiInstanceType {
365    JavaScriptObject,
366    InnerGlobalObject,
367    OuterGlobalObject
368  };
369
370  Handle<JSFunction> CreateApiFunction(
371      Handle<FunctionTemplateInfo> data,
372      ApiInstanceType type = JavaScriptObject);
373
374  Handle<JSFunction> InstallMembers(Handle<JSFunction> function);
375
376  // Installs interceptors on the instance.  'desc' is a function template,
377  // and instance is an object instance created by the function of this
378  // function template.
379  void ConfigureInstance(Handle<FunctionTemplateInfo> desc,
380                         Handle<JSObject> instance,
381                         bool* pending_exception);
382
383#define ROOT_ACCESSOR(type, name, camel_name)                                  \
384  inline Handle<type> name() {                                                 \
385    return Handle<type>(BitCast<type**>(                                       \
386        &isolate()->heap()->roots_[Heap::k##camel_name##RootIndex]));          \
387  }
388  ROOT_LIST(ROOT_ACCESSOR)
389#undef ROOT_ACCESSOR_ACCESSOR
390
391#define SYMBOL_ACCESSOR(name, str)                                             \
392  inline Handle<String> name() {                                               \
393    return Handle<String>(BitCast<String**>(                                   \
394        &isolate()->heap()->roots_[Heap::k##name##RootIndex]));                \
395  }
396  SYMBOL_LIST(SYMBOL_ACCESSOR)
397#undef SYMBOL_ACCESSOR
398
399  Handle<String> hidden_symbol() {
400    return Handle<String>(&isolate()->heap()->hidden_symbol_);
401  }
402
403  Handle<SharedFunctionInfo> NewSharedFunctionInfo(
404      Handle<String> name,
405      int number_of_literals,
406      Handle<Code> code,
407      Handle<SerializedScopeInfo> scope_info);
408  Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
409
410  Handle<JSMessageObject> NewJSMessageObject(
411      Handle<String> type,
412      Handle<JSArray> arguments,
413      int start_position,
414      int end_position,
415      Handle<Object> script,
416      Handle<Object> stack_trace,
417      Handle<Object> stack_frames);
418
419  Handle<SeededNumberDictionary> DictionaryAtNumberPut(
420      Handle<SeededNumberDictionary>,
421      uint32_t key,
422      Handle<Object> value);
423
424  Handle<UnseededNumberDictionary> DictionaryAtNumberPut(
425      Handle<UnseededNumberDictionary>,
426      uint32_t key,
427      Handle<Object> value);
428
429#ifdef ENABLE_DEBUGGER_SUPPORT
430  Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
431#endif
432
433  // Return a map using the map cache in the global context.
434  // The key the an ordered set of property names.
435  Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context,
436                                        Handle<FixedArray> keys);
437
438  // Creates a new FixedArray that holds the data associated with the
439  // atom regexp and stores it in the regexp.
440  void SetRegExpAtomData(Handle<JSRegExp> regexp,
441                         JSRegExp::Type type,
442                         Handle<String> source,
443                         JSRegExp::Flags flags,
444                         Handle<Object> match_pattern);
445
446  // Creates a new FixedArray that holds the data associated with the
447  // irregexp regexp and stores it in the regexp.
448  void SetRegExpIrregexpData(Handle<JSRegExp> regexp,
449                             JSRegExp::Type type,
450                             Handle<String> source,
451                             JSRegExp::Flags flags,
452                             int capture_count);
453
454 private:
455  Isolate* isolate() { return reinterpret_cast<Isolate*>(this); }
456
457  Handle<JSFunction> NewFunctionHelper(Handle<String> name,
458                                       Handle<Object> prototype);
459
460  Handle<JSFunction> NewFunctionWithoutPrototypeHelper(
461      Handle<String> name,
462      StrictModeFlag strict_mode);
463
464  Handle<DescriptorArray> CopyAppendCallbackDescriptors(
465      Handle<DescriptorArray> array,
466      Handle<Object> descriptors);
467
468  // Create a new map cache.
469  Handle<MapCache> NewMapCache(int at_least_space_for);
470
471  // Update the map cache in the global context with (keys, map)
472  Handle<MapCache> AddToMapCache(Handle<Context> context,
473                                 Handle<FixedArray> keys,
474                                 Handle<Map> map);
475};
476
477
478} }  // namespace v8::internal
479
480#endif  // V8_FACTORY_H_
481