• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2006-2008 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 #include "v8.h"
29 
30 #include "api.h"
31 #include "debug.h"
32 #include "execution.h"
33 #include "factory.h"
34 #include "macro-assembler.h"
35 
36 namespace v8 {
37 namespace internal {
38 
39 
NewFixedArray(int size,PretenureFlag pretenure)40 Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) {
41   ASSERT(0 <= size);
42   CALL_HEAP_FUNCTION(Heap::AllocateFixedArray(size, pretenure), FixedArray);
43 }
44 
45 
NewFixedArrayWithHoles(int size)46 Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size) {
47   ASSERT(0 <= size);
48   CALL_HEAP_FUNCTION(Heap::AllocateFixedArrayWithHoles(size), FixedArray);
49 }
50 
51 
NewStringDictionary(int at_least_space_for)52 Handle<StringDictionary> Factory::NewStringDictionary(int at_least_space_for) {
53   ASSERT(0 <= at_least_space_for);
54   CALL_HEAP_FUNCTION(StringDictionary::Allocate(at_least_space_for),
55                      StringDictionary);
56 }
57 
58 
NewNumberDictionary(int at_least_space_for)59 Handle<NumberDictionary> Factory::NewNumberDictionary(int at_least_space_for) {
60   ASSERT(0 <= at_least_space_for);
61   CALL_HEAP_FUNCTION(NumberDictionary::Allocate(at_least_space_for),
62                      NumberDictionary);
63 }
64 
65 
NewDescriptorArray(int number_of_descriptors)66 Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors) {
67   ASSERT(0 <= number_of_descriptors);
68   CALL_HEAP_FUNCTION(DescriptorArray::Allocate(number_of_descriptors),
69                      DescriptorArray);
70 }
71 
72 
73 // Symbols are created in the old generation (data space).
LookupSymbol(Vector<const char> string)74 Handle<String> Factory::LookupSymbol(Vector<const char> string) {
75   CALL_HEAP_FUNCTION(Heap::LookupSymbol(string), String);
76 }
77 
78 
NewStringFromAscii(Vector<const char> string,PretenureFlag pretenure)79 Handle<String> Factory::NewStringFromAscii(Vector<const char> string,
80                                            PretenureFlag pretenure) {
81   CALL_HEAP_FUNCTION(Heap::AllocateStringFromAscii(string, pretenure), String);
82 }
83 
NewStringFromUtf8(Vector<const char> string,PretenureFlag pretenure)84 Handle<String> Factory::NewStringFromUtf8(Vector<const char> string,
85                                           PretenureFlag pretenure) {
86   CALL_HEAP_FUNCTION(Heap::AllocateStringFromUtf8(string, pretenure), String);
87 }
88 
89 
NewStringFromTwoByte(Vector<const uc16> string,PretenureFlag pretenure)90 Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
91                                              PretenureFlag pretenure) {
92   CALL_HEAP_FUNCTION(Heap::AllocateStringFromTwoByte(string, pretenure),
93                      String);
94 }
95 
96 
NewRawTwoByteString(int length,PretenureFlag pretenure)97 Handle<String> Factory::NewRawTwoByteString(int length,
98                                             PretenureFlag pretenure) {
99   CALL_HEAP_FUNCTION(Heap::AllocateRawTwoByteString(length, pretenure), String);
100 }
101 
102 
NewConsString(Handle<String> first,Handle<String> second)103 Handle<String> Factory::NewConsString(Handle<String> first,
104                                       Handle<String> second) {
105   CALL_HEAP_FUNCTION(Heap::AllocateConsString(*first, *second), String);
106 }
107 
108 
NewStringSlice(Handle<String> str,int begin,int end)109 Handle<String> Factory::NewStringSlice(Handle<String> str,
110                                        int begin,
111                                        int end) {
112   CALL_HEAP_FUNCTION(str->Slice(begin, end), String);
113 }
114 
115 
NewExternalStringFromAscii(ExternalAsciiString::Resource * resource)116 Handle<String> Factory::NewExternalStringFromAscii(
117     ExternalAsciiString::Resource* resource) {
118   CALL_HEAP_FUNCTION(Heap::AllocateExternalStringFromAscii(resource), String);
119 }
120 
121 
NewExternalStringFromTwoByte(ExternalTwoByteString::Resource * resource)122 Handle<String> Factory::NewExternalStringFromTwoByte(
123     ExternalTwoByteString::Resource* resource) {
124   CALL_HEAP_FUNCTION(Heap::AllocateExternalStringFromTwoByte(resource), String);
125 }
126 
127 
NewGlobalContext()128 Handle<Context> Factory::NewGlobalContext() {
129   CALL_HEAP_FUNCTION(Heap::AllocateGlobalContext(), Context);
130 }
131 
132 
NewFunctionContext(int length,Handle<JSFunction> closure)133 Handle<Context> Factory::NewFunctionContext(int length,
134                                             Handle<JSFunction> closure) {
135   CALL_HEAP_FUNCTION(Heap::AllocateFunctionContext(length, *closure), Context);
136 }
137 
138 
NewWithContext(Handle<Context> previous,Handle<JSObject> extension,bool is_catch_context)139 Handle<Context> Factory::NewWithContext(Handle<Context> previous,
140                                         Handle<JSObject> extension,
141                                         bool is_catch_context) {
142   CALL_HEAP_FUNCTION(Heap::AllocateWithContext(*previous,
143                                                *extension,
144                                                is_catch_context),
145                      Context);
146 }
147 
148 
NewStruct(InstanceType type)149 Handle<Struct> Factory::NewStruct(InstanceType type) {
150   CALL_HEAP_FUNCTION(Heap::AllocateStruct(type), Struct);
151 }
152 
153 
NewAccessorInfo()154 Handle<AccessorInfo> Factory::NewAccessorInfo() {
155   Handle<AccessorInfo> info =
156       Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE));
157   info->set_flag(0);  // Must clear the flag, it was initialized as undefined.
158   return info;
159 }
160 
161 
NewScript(Handle<String> source)162 Handle<Script> Factory::NewScript(Handle<String> source) {
163   // Generate id for this script.
164   int id;
165   if (Heap::last_script_id()->IsUndefined()) {
166     // Script ids start from one.
167     id = 1;
168   } else {
169     // Increment id, wrap when positive smi is exhausted.
170     id = Smi::cast(Heap::last_script_id())->value();
171     id++;
172     if (!Smi::IsValid(id)) {
173       id = 0;
174     }
175   }
176   Heap::SetLastScriptId(Smi::FromInt(id));
177 
178   // Create and initialize script object.
179   Handle<Proxy> wrapper = Factory::NewProxy(0, TENURED);
180   Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
181   script->set_source(*source);
182   script->set_name(Heap::undefined_value());
183   script->set_id(Heap::last_script_id());
184   script->set_line_offset(Smi::FromInt(0));
185   script->set_column_offset(Smi::FromInt(0));
186   script->set_data(Heap::undefined_value());
187   script->set_context_data(Heap::undefined_value());
188   script->set_type(Smi::FromInt(Script::TYPE_NORMAL));
189   script->set_compilation_type(Smi::FromInt(Script::COMPILATION_TYPE_HOST));
190   script->set_wrapper(*wrapper);
191   script->set_line_ends(Heap::undefined_value());
192   script->set_eval_from_function(Heap::undefined_value());
193   script->set_eval_from_instructions_offset(Smi::FromInt(0));
194 
195   return script;
196 }
197 
198 
NewProxy(Address addr,PretenureFlag pretenure)199 Handle<Proxy> Factory::NewProxy(Address addr, PretenureFlag pretenure) {
200   CALL_HEAP_FUNCTION(Heap::AllocateProxy(addr, pretenure), Proxy);
201 }
202 
203 
NewProxy(const AccessorDescriptor * desc)204 Handle<Proxy> Factory::NewProxy(const AccessorDescriptor* desc) {
205   return NewProxy((Address) desc, TENURED);
206 }
207 
208 
NewByteArray(int length,PretenureFlag pretenure)209 Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) {
210   ASSERT(0 <= length);
211   CALL_HEAP_FUNCTION(Heap::AllocateByteArray(length, pretenure), ByteArray);
212 }
213 
214 
NewPixelArray(int length,uint8_t * external_pointer,PretenureFlag pretenure)215 Handle<PixelArray> Factory::NewPixelArray(int length,
216                                           uint8_t* external_pointer,
217                                           PretenureFlag pretenure) {
218   ASSERT(0 <= length);
219   CALL_HEAP_FUNCTION(Heap::AllocatePixelArray(length,
220                                               external_pointer,
221                                               pretenure), PixelArray);
222 }
223 
224 
NewMap(InstanceType type,int instance_size)225 Handle<Map> Factory::NewMap(InstanceType type, int instance_size) {
226   CALL_HEAP_FUNCTION(Heap::AllocateMap(type, instance_size), Map);
227 }
228 
229 
NewFunctionPrototype(Handle<JSFunction> function)230 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
231   CALL_HEAP_FUNCTION(Heap::AllocateFunctionPrototype(*function), JSObject);
232 }
233 
234 
CopyMapDropDescriptors(Handle<Map> src)235 Handle<Map> Factory::CopyMapDropDescriptors(Handle<Map> src) {
236   CALL_HEAP_FUNCTION(src->CopyDropDescriptors(), Map);
237 }
238 
239 
CopyMap(Handle<Map> src,int extra_inobject_properties)240 Handle<Map> Factory::CopyMap(Handle<Map> src,
241                              int extra_inobject_properties) {
242   Handle<Map> copy = CopyMapDropDescriptors(src);
243   // Check that we do not overflow the instance size when adding the
244   // extra inobject properties.
245   int instance_size_delta = extra_inobject_properties * kPointerSize;
246   int max_instance_size_delta =
247       JSObject::kMaxInstanceSize - copy->instance_size();
248   if (instance_size_delta > max_instance_size_delta) {
249     // If the instance size overflows, we allocate as many properties
250     // as we can as inobject properties.
251     instance_size_delta = max_instance_size_delta;
252     extra_inobject_properties = max_instance_size_delta >> kPointerSizeLog2;
253   }
254   // Adjust the map with the extra inobject properties.
255   int inobject_properties =
256       copy->inobject_properties() + extra_inobject_properties;
257   copy->set_inobject_properties(inobject_properties);
258   copy->set_unused_property_fields(inobject_properties);
259   copy->set_instance_size(copy->instance_size() + instance_size_delta);
260   return copy;
261 }
262 
CopyMapDropTransitions(Handle<Map> src)263 Handle<Map> Factory::CopyMapDropTransitions(Handle<Map> src) {
264   CALL_HEAP_FUNCTION(src->CopyDropTransitions(), Map);
265 }
266 
267 
CopyFixedArray(Handle<FixedArray> array)268 Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
269   CALL_HEAP_FUNCTION(array->Copy(), FixedArray);
270 }
271 
272 
BaseNewFunctionFromBoilerplate(Handle<JSFunction> boilerplate,Handle<Map> function_map)273 Handle<JSFunction> Factory::BaseNewFunctionFromBoilerplate(
274     Handle<JSFunction> boilerplate,
275     Handle<Map> function_map) {
276   ASSERT(boilerplate->IsBoilerplate());
277   ASSERT(!boilerplate->has_initial_map());
278   ASSERT(!boilerplate->has_prototype());
279   ASSERT(boilerplate->properties() == Heap::empty_fixed_array());
280   ASSERT(boilerplate->elements() == Heap::empty_fixed_array());
281   CALL_HEAP_FUNCTION(Heap::AllocateFunction(*function_map,
282                                             boilerplate->shared(),
283                                             Heap::the_hole_value()),
284                      JSFunction);
285 }
286 
287 
NewFunctionFromBoilerplate(Handle<JSFunction> boilerplate,Handle<Context> context)288 Handle<JSFunction> Factory::NewFunctionFromBoilerplate(
289     Handle<JSFunction> boilerplate,
290     Handle<Context> context) {
291   Handle<JSFunction> result =
292       BaseNewFunctionFromBoilerplate(boilerplate, Top::function_map());
293   result->set_context(*context);
294   int number_of_literals = boilerplate->NumberOfLiterals();
295   Handle<FixedArray> literals =
296       Factory::NewFixedArray(number_of_literals, TENURED);
297   if (number_of_literals > 0) {
298     // Store the object, regexp and array functions in the literals
299     // array prefix.  These functions will be used when creating
300     // object, regexp and array literals in this function.
301     literals->set(JSFunction::kLiteralGlobalContextIndex,
302                   context->global_context());
303   }
304   result->set_literals(*literals);
305   ASSERT(!result->IsBoilerplate());
306   return result;
307 }
308 
309 
NewNumber(double value,PretenureFlag pretenure)310 Handle<Object> Factory::NewNumber(double value,
311                                   PretenureFlag pretenure) {
312   CALL_HEAP_FUNCTION(Heap::NumberFromDouble(value, pretenure), Object);
313 }
314 
315 
NewNumberFromInt(int value)316 Handle<Object> Factory::NewNumberFromInt(int value) {
317   CALL_HEAP_FUNCTION(Heap::NumberFromInt32(value), Object);
318 }
319 
320 
NewNumberFromUint(uint32_t value)321 Handle<Object> Factory::NewNumberFromUint(uint32_t value) {
322   CALL_HEAP_FUNCTION(Heap::NumberFromUint32(value), Object);
323 }
324 
325 
NewNeanderObject()326 Handle<JSObject> Factory::NewNeanderObject() {
327   CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(Heap::neander_map()),
328                      JSObject);
329 }
330 
331 
NewTypeError(const char * type,Vector<Handle<Object>> args)332 Handle<Object> Factory::NewTypeError(const char* type,
333                                      Vector< Handle<Object> > args) {
334   return NewError("MakeTypeError", type, args);
335 }
336 
337 
NewTypeError(Handle<String> message)338 Handle<Object> Factory::NewTypeError(Handle<String> message) {
339   return NewError("$TypeError", message);
340 }
341 
342 
NewRangeError(const char * type,Vector<Handle<Object>> args)343 Handle<Object> Factory::NewRangeError(const char* type,
344                                       Vector< Handle<Object> > args) {
345   return NewError("MakeRangeError", type, args);
346 }
347 
348 
NewRangeError(Handle<String> message)349 Handle<Object> Factory::NewRangeError(Handle<String> message) {
350   return NewError("$RangeError", message);
351 }
352 
353 
NewSyntaxError(const char * type,Handle<JSArray> args)354 Handle<Object> Factory::NewSyntaxError(const char* type, Handle<JSArray> args) {
355   return NewError("MakeSyntaxError", type, args);
356 }
357 
358 
NewSyntaxError(Handle<String> message)359 Handle<Object> Factory::NewSyntaxError(Handle<String> message) {
360   return NewError("$SyntaxError", message);
361 }
362 
363 
NewReferenceError(const char * type,Vector<Handle<Object>> args)364 Handle<Object> Factory::NewReferenceError(const char* type,
365                                           Vector< Handle<Object> > args) {
366   return NewError("MakeReferenceError", type, args);
367 }
368 
369 
NewReferenceError(Handle<String> message)370 Handle<Object> Factory::NewReferenceError(Handle<String> message) {
371   return NewError("$ReferenceError", message);
372 }
373 
374 
NewError(const char * maker,const char * type,Vector<Handle<Object>> args)375 Handle<Object> Factory::NewError(const char* maker, const char* type,
376     Vector< Handle<Object> > args) {
377   v8::HandleScope scope;  // Instantiate a closeable HandleScope for EscapeFrom.
378   Handle<FixedArray> array = Factory::NewFixedArray(args.length());
379   for (int i = 0; i < args.length(); i++) {
380     array->set(i, *args[i]);
381   }
382   Handle<JSArray> object = Factory::NewJSArrayWithElements(array);
383   Handle<Object> result = NewError(maker, type, object);
384   return result.EscapeFrom(&scope);
385 }
386 
387 
NewEvalError(const char * type,Vector<Handle<Object>> args)388 Handle<Object> Factory::NewEvalError(const char* type,
389                                      Vector< Handle<Object> > args) {
390   return NewError("MakeEvalError", type, args);
391 }
392 
393 
NewError(const char * type,Vector<Handle<Object>> args)394 Handle<Object> Factory::NewError(const char* type,
395                                  Vector< Handle<Object> > args) {
396   return NewError("MakeError", type, args);
397 }
398 
399 
NewError(const char * maker,const char * type,Handle<JSArray> args)400 Handle<Object> Factory::NewError(const char* maker,
401                                  const char* type,
402                                  Handle<JSArray> args) {
403   Handle<String> make_str = Factory::LookupAsciiSymbol(maker);
404   Handle<JSFunction> fun =
405       Handle<JSFunction>(
406           JSFunction::cast(
407               Top::builtins()->GetProperty(*make_str)));
408   Handle<Object> type_obj = Factory::LookupAsciiSymbol(type);
409   Object** argv[2] = { type_obj.location(),
410                        Handle<Object>::cast(args).location() };
411 
412   // Invoke the JavaScript factory method. If an exception is thrown while
413   // running the factory method, use the exception as the result.
414   bool caught_exception;
415   Handle<Object> result = Execution::TryCall(fun,
416                                              Top::builtins(),
417                                              2,
418                                              argv,
419                                              &caught_exception);
420   return result;
421 }
422 
423 
NewError(Handle<String> message)424 Handle<Object> Factory::NewError(Handle<String> message) {
425   return NewError("$Error", message);
426 }
427 
428 
NewError(const char * constructor,Handle<String> message)429 Handle<Object> Factory::NewError(const char* constructor,
430                                  Handle<String> message) {
431   Handle<String> constr = Factory::LookupAsciiSymbol(constructor);
432   Handle<JSFunction> fun =
433       Handle<JSFunction>(
434           JSFunction::cast(
435               Top::builtins()->GetProperty(*constr)));
436   Object** argv[1] = { Handle<Object>::cast(message).location() };
437 
438   // Invoke the JavaScript factory method. If an exception is thrown while
439   // running the factory method, use the exception as the result.
440   bool caught_exception;
441   Handle<Object> result = Execution::TryCall(fun,
442                                              Top::builtins(),
443                                              1,
444                                              argv,
445                                              &caught_exception);
446   return result;
447 }
448 
449 
NewFunction(Handle<String> name,InstanceType type,int instance_size,Handle<Code> code,bool force_initial_map)450 Handle<JSFunction> Factory::NewFunction(Handle<String> name,
451                                         InstanceType type,
452                                         int instance_size,
453                                         Handle<Code> code,
454                                         bool force_initial_map) {
455   // Allocate the function
456   Handle<JSFunction> function = NewFunction(name, the_hole_value());
457   function->set_code(*code);
458 
459   if (force_initial_map ||
460       type != JS_OBJECT_TYPE ||
461       instance_size != JSObject::kHeaderSize) {
462     Handle<Map> initial_map = NewMap(type, instance_size);
463     Handle<JSObject> prototype = NewFunctionPrototype(function);
464     initial_map->set_prototype(*prototype);
465     function->set_initial_map(*initial_map);
466     initial_map->set_constructor(*function);
467   } else {
468     ASSERT(!function->has_initial_map());
469     ASSERT(!function->has_prototype());
470   }
471 
472   return function;
473 }
474 
475 
NewFunctionBoilerplate(Handle<String> name,int number_of_literals,bool contains_array_literal,Handle<Code> code)476 Handle<JSFunction> Factory::NewFunctionBoilerplate(Handle<String> name,
477                                                    int number_of_literals,
478                                                    bool contains_array_literal,
479                                                    Handle<Code> code) {
480   Handle<JSFunction> function = NewFunctionBoilerplate(name);
481   function->set_code(*code);
482   int literals_array_size = number_of_literals;
483   // If the function contains object, regexp or array literals,
484   // allocate extra space for a literals array prefix containing the
485   // object, regexp and array constructor functions.
486   if (number_of_literals > 0 || contains_array_literal) {
487     literals_array_size += JSFunction::kLiteralsPrefixSize;
488   }
489   Handle<FixedArray> literals =
490       Factory::NewFixedArray(literals_array_size, TENURED);
491   function->set_literals(*literals);
492   ASSERT(!function->has_initial_map());
493   ASSERT(!function->has_prototype());
494   return function;
495 }
496 
497 
NewFunctionBoilerplate(Handle<String> name)498 Handle<JSFunction> Factory::NewFunctionBoilerplate(Handle<String> name) {
499   Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
500   CALL_HEAP_FUNCTION(Heap::AllocateFunction(Heap::boilerplate_function_map(),
501                                             *shared,
502                                             Heap::the_hole_value()),
503                      JSFunction);
504 }
505 
506 
NewFunctionWithPrototype(Handle<String> name,InstanceType type,int instance_size,Handle<JSObject> prototype,Handle<Code> code,bool force_initial_map)507 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
508                                                      InstanceType type,
509                                                      int instance_size,
510                                                      Handle<JSObject> prototype,
511                                                      Handle<Code> code,
512                                                      bool force_initial_map) {
513   // Allocate the function
514   Handle<JSFunction> function = NewFunction(name, prototype);
515 
516   function->set_code(*code);
517 
518   if (force_initial_map ||
519       type != JS_OBJECT_TYPE ||
520       instance_size != JSObject::kHeaderSize) {
521     Handle<Map> initial_map = NewMap(type, instance_size);
522     function->set_initial_map(*initial_map);
523     initial_map->set_constructor(*function);
524   }
525 
526   // Set function.prototype and give the prototype a constructor
527   // property that refers to the function.
528   SetPrototypeProperty(function, prototype);
529   SetProperty(prototype, Factory::constructor_symbol(), function, DONT_ENUM);
530   return function;
531 }
532 
533 
NewCode(const CodeDesc & desc,ZoneScopeInfo * sinfo,Code::Flags flags,Handle<Object> self_ref)534 Handle<Code> Factory::NewCode(const CodeDesc& desc,
535                               ZoneScopeInfo* sinfo,
536                               Code::Flags flags,
537                               Handle<Object> self_ref) {
538   CALL_HEAP_FUNCTION(Heap::CreateCode(desc, sinfo, flags, self_ref), Code);
539 }
540 
541 
CopyCode(Handle<Code> code)542 Handle<Code> Factory::CopyCode(Handle<Code> code) {
543   CALL_HEAP_FUNCTION(Heap::CopyCode(*code), Code);
544 }
545 
546 
DoCopyInsert(DescriptorArray * array,String * key,Object * value,PropertyAttributes attributes)547 static inline Object* DoCopyInsert(DescriptorArray* array,
548                                    String* key,
549                                    Object* value,
550                                    PropertyAttributes attributes) {
551   CallbacksDescriptor desc(key, value, attributes);
552   Object* obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS);
553   return obj;
554 }
555 
556 
557 // Allocate the new array.
CopyAppendProxyDescriptor(Handle<DescriptorArray> array,Handle<String> key,Handle<Object> value,PropertyAttributes attributes)558 Handle<DescriptorArray> Factory::CopyAppendProxyDescriptor(
559     Handle<DescriptorArray> array,
560     Handle<String> key,
561     Handle<Object> value,
562     PropertyAttributes attributes) {
563   CALL_HEAP_FUNCTION(DoCopyInsert(*array, *key, *value, attributes),
564                      DescriptorArray);
565 }
566 
567 
SymbolFromString(Handle<String> value)568 Handle<String> Factory::SymbolFromString(Handle<String> value) {
569   CALL_HEAP_FUNCTION(Heap::LookupSymbol(*value), String);
570 }
571 
572 
CopyAppendCallbackDescriptors(Handle<DescriptorArray> array,Handle<Object> descriptors)573 Handle<DescriptorArray> Factory::CopyAppendCallbackDescriptors(
574     Handle<DescriptorArray> array,
575     Handle<Object> descriptors) {
576   v8::NeanderArray callbacks(descriptors);
577   int nof_callbacks = callbacks.length();
578   Handle<DescriptorArray> result =
579       NewDescriptorArray(array->number_of_descriptors() + nof_callbacks);
580 
581   // Number of descriptors added to the result so far.
582   int descriptor_count = 0;
583 
584   // Copy the descriptors from the array.
585   for (int i = 0; i < array->number_of_descriptors(); i++) {
586     if (array->GetType(i) != NULL_DESCRIPTOR) {
587       result->CopyFrom(descriptor_count++, *array, i);
588     }
589   }
590 
591   // Number of duplicates detected.
592   int duplicates = 0;
593 
594   // Fill in new callback descriptors.  Process the callbacks from
595   // back to front so that the last callback with a given name takes
596   // precedence over previously added callbacks with that name.
597   for (int i = nof_callbacks - 1; i >= 0; i--) {
598     Handle<AccessorInfo> entry =
599         Handle<AccessorInfo>(AccessorInfo::cast(callbacks.get(i)));
600     // Ensure the key is a symbol before writing into the instance descriptor.
601     Handle<String> key =
602         SymbolFromString(Handle<String>(String::cast(entry->name())));
603     // Check if a descriptor with this name already exists before writing.
604     if (result->LinearSearch(*key, descriptor_count) ==
605         DescriptorArray::kNotFound) {
606       CallbacksDescriptor desc(*key, *entry, entry->property_attributes());
607       result->Set(descriptor_count, &desc);
608       descriptor_count++;
609     } else {
610       duplicates++;
611     }
612   }
613 
614   // If duplicates were detected, allocate a result of the right size
615   // and transfer the elements.
616   if (duplicates > 0) {
617     int number_of_descriptors = result->number_of_descriptors() - duplicates;
618     Handle<DescriptorArray> new_result =
619         NewDescriptorArray(number_of_descriptors);
620     for (int i = 0; i < number_of_descriptors; i++) {
621       new_result->CopyFrom(i, *result, i);
622     }
623     result = new_result;
624   }
625 
626   // Sort the result before returning.
627   result->Sort();
628   return result;
629 }
630 
631 
NewJSObject(Handle<JSFunction> constructor,PretenureFlag pretenure)632 Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
633                                       PretenureFlag pretenure) {
634   CALL_HEAP_FUNCTION(Heap::AllocateJSObject(*constructor, pretenure), JSObject);
635 }
636 
637 
NewGlobalObject(Handle<JSFunction> constructor)638 Handle<GlobalObject> Factory::NewGlobalObject(
639     Handle<JSFunction> constructor) {
640   CALL_HEAP_FUNCTION(Heap::AllocateGlobalObject(*constructor),
641                      GlobalObject);
642 }
643 
644 
645 
NewJSObjectFromMap(Handle<Map> map)646 Handle<JSObject> Factory::NewJSObjectFromMap(Handle<Map> map) {
647   CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(*map, NOT_TENURED),
648                      JSObject);
649 }
650 
651 
NewJSArray(int length,PretenureFlag pretenure)652 Handle<JSArray> Factory::NewJSArray(int length,
653                                     PretenureFlag pretenure) {
654   Handle<JSObject> obj = NewJSObject(Top::array_function(), pretenure);
655   CALL_HEAP_FUNCTION(Handle<JSArray>::cast(obj)->Initialize(length), JSArray);
656 }
657 
658 
NewJSArrayWithElements(Handle<FixedArray> elements,PretenureFlag pretenure)659 Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArray> elements,
660                                                 PretenureFlag pretenure) {
661   Handle<JSArray> result =
662       Handle<JSArray>::cast(NewJSObject(Top::array_function(), pretenure));
663   result->SetContent(*elements);
664   return result;
665 }
666 
667 
NewSharedFunctionInfo(Handle<String> name)668 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) {
669   CALL_HEAP_FUNCTION(Heap::AllocateSharedFunctionInfo(*name),
670                      SharedFunctionInfo);
671 }
672 
673 
DictionaryAtNumberPut(Handle<NumberDictionary> dictionary,uint32_t key,Handle<Object> value)674 Handle<NumberDictionary> Factory::DictionaryAtNumberPut(
675     Handle<NumberDictionary> dictionary,
676     uint32_t key,
677     Handle<Object> value) {
678   CALL_HEAP_FUNCTION(dictionary->AtNumberPut(key, *value), NumberDictionary);
679 }
680 
681 
NewFunctionHelper(Handle<String> name,Handle<Object> prototype)682 Handle<JSFunction> Factory::NewFunctionHelper(Handle<String> name,
683                                               Handle<Object> prototype) {
684   Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
685   CALL_HEAP_FUNCTION(Heap::AllocateFunction(*Top::function_map(),
686                                             *function_share,
687                                             *prototype),
688                      JSFunction);
689 }
690 
691 
NewFunction(Handle<String> name,Handle<Object> prototype)692 Handle<JSFunction> Factory::NewFunction(Handle<String> name,
693                                         Handle<Object> prototype) {
694   Handle<JSFunction> fun = NewFunctionHelper(name, prototype);
695   fun->set_context(Top::context()->global_context());
696   return fun;
697 }
698 
699 
ToObject(Handle<Object> object,Handle<Context> global_context)700 Handle<Object> Factory::ToObject(Handle<Object> object,
701                                  Handle<Context> global_context) {
702   CALL_HEAP_FUNCTION(object->ToObject(*global_context), Object);
703 }
704 
705 
706 #ifdef ENABLE_DEBUGGER_SUPPORT
NewDebugInfo(Handle<SharedFunctionInfo> shared)707 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
708   // Get the original code of the function.
709   Handle<Code> code(shared->code());
710 
711   // Create a copy of the code before allocating the debug info object to avoid
712   // allocation while setting up the debug info object.
713   Handle<Code> original_code(*Factory::CopyCode(code));
714 
715   // Allocate initial fixed array for active break points before allocating the
716   // debug info object to avoid allocation while setting up the debug info
717   // object.
718   Handle<FixedArray> break_points(
719       Factory::NewFixedArray(Debug::kEstimatedNofBreakPointsInFunction));
720 
721   // Create and set up the debug info object. Debug info contains function, a
722   // copy of the original code, the executing code and initial fixed array for
723   // active break points.
724   Handle<DebugInfo> debug_info =
725       Handle<DebugInfo>::cast(Factory::NewStruct(DEBUG_INFO_TYPE));
726   debug_info->set_shared(*shared);
727   debug_info->set_original_code(*original_code);
728   debug_info->set_code(*code);
729   debug_info->set_break_points(*break_points);
730 
731   // Link debug info to function.
732   shared->set_debug_info(*debug_info);
733 
734   return debug_info;
735 }
736 #endif
737 
738 
NewArgumentsObject(Handle<Object> callee,int length)739 Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee,
740                                              int length) {
741   CALL_HEAP_FUNCTION(Heap::AllocateArgumentsObject(*callee, length), JSObject);
742 }
743 
744 
CreateApiFunction(Handle<FunctionTemplateInfo> obj,ApiInstanceType instance_type)745 Handle<JSFunction> Factory::CreateApiFunction(
746     Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) {
747   Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::HandleApiCall));
748 
749   int internal_field_count = 0;
750   if (!obj->instance_template()->IsUndefined()) {
751     Handle<ObjectTemplateInfo> instance_template =
752         Handle<ObjectTemplateInfo>(
753             ObjectTemplateInfo::cast(obj->instance_template()));
754     internal_field_count =
755         Smi::cast(instance_template->internal_field_count())->value();
756   }
757 
758   int instance_size = kPointerSize * internal_field_count;
759   InstanceType type = INVALID_TYPE;
760   switch (instance_type) {
761     case JavaScriptObject:
762       type = JS_OBJECT_TYPE;
763       instance_size += JSObject::kHeaderSize;
764       break;
765     case InnerGlobalObject:
766       type = JS_GLOBAL_OBJECT_TYPE;
767       instance_size += JSGlobalObject::kSize;
768       break;
769     case OuterGlobalObject:
770       type = JS_GLOBAL_PROXY_TYPE;
771       instance_size += JSGlobalProxy::kSize;
772       break;
773     default:
774       break;
775   }
776   ASSERT(type != INVALID_TYPE);
777 
778   Handle<JSFunction> result =
779       Factory::NewFunction(Factory::empty_symbol(),
780                            type,
781                            instance_size,
782                            code,
783                            true);
784   // Set class name.
785   Handle<Object> class_name = Handle<Object>(obj->class_name());
786   if (class_name->IsString()) {
787     result->shared()->set_instance_class_name(*class_name);
788     result->shared()->set_name(*class_name);
789   }
790 
791   Handle<Map> map = Handle<Map>(result->initial_map());
792 
793   // Mark as undetectable if needed.
794   if (obj->undetectable()) {
795     map->set_is_undetectable();
796   }
797 
798   // Mark as hidden for the __proto__ accessor if needed.
799   if (obj->hidden_prototype()) {
800     map->set_is_hidden_prototype();
801   }
802 
803   // Mark as needs_access_check if needed.
804   if (obj->needs_access_check()) {
805     map->set_is_access_check_needed(true);
806   }
807 
808   // Set interceptor information in the map.
809   if (!obj->named_property_handler()->IsUndefined()) {
810     map->set_has_named_interceptor();
811   }
812   if (!obj->indexed_property_handler()->IsUndefined()) {
813     map->set_has_indexed_interceptor();
814   }
815 
816   // Set instance call-as-function information in the map.
817   if (!obj->instance_call_handler()->IsUndefined()) {
818     map->set_has_instance_call_handler();
819   }
820 
821   result->shared()->set_function_data(*obj);
822   result->shared()->DontAdaptArguments();
823 
824   // Recursively copy parent templates' accessors, 'data' may be modified.
825   Handle<DescriptorArray> array =
826       Handle<DescriptorArray>(map->instance_descriptors());
827   while (true) {
828     Handle<Object> props = Handle<Object>(obj->property_accessors());
829     if (!props->IsUndefined()) {
830       array = Factory::CopyAppendCallbackDescriptors(array, props);
831     }
832     Handle<Object> parent = Handle<Object>(obj->parent_template());
833     if (parent->IsUndefined()) break;
834     obj = Handle<FunctionTemplateInfo>::cast(parent);
835   }
836   if (!array->IsEmpty()) {
837     map->set_instance_descriptors(*array);
838   }
839 
840   return result;
841 }
842 
843 
NewMapCache(int at_least_space_for)844 Handle<MapCache> Factory::NewMapCache(int at_least_space_for) {
845   CALL_HEAP_FUNCTION(MapCache::Allocate(at_least_space_for), MapCache);
846 }
847 
848 
UpdateMapCacheWith(Context * context,FixedArray * keys,Map * map)849 static Object* UpdateMapCacheWith(Context* context,
850                                   FixedArray* keys,
851                                   Map* map) {
852   Object* result = MapCache::cast(context->map_cache())->Put(keys, map);
853   if (!result->IsFailure()) context->set_map_cache(MapCache::cast(result));
854   return result;
855 }
856 
857 
AddToMapCache(Handle<Context> context,Handle<FixedArray> keys,Handle<Map> map)858 Handle<MapCache> Factory::AddToMapCache(Handle<Context> context,
859                                         Handle<FixedArray> keys,
860                                         Handle<Map> map) {
861   CALL_HEAP_FUNCTION(UpdateMapCacheWith(*context, *keys, *map), MapCache);
862 }
863 
864 
ObjectLiteralMapFromCache(Handle<Context> context,Handle<FixedArray> keys)865 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
866                                                Handle<FixedArray> keys) {
867   if (context->map_cache()->IsUndefined()) {
868     // Allocate the new map cache for the global context.
869     Handle<MapCache> new_cache = NewMapCache(24);
870     context->set_map_cache(*new_cache);
871   }
872   // Check to see whether there is a matching element in the cache.
873   Handle<MapCache> cache =
874       Handle<MapCache>(MapCache::cast(context->map_cache()));
875   Handle<Object> result = Handle<Object>(cache->Lookup(*keys));
876   if (result->IsMap()) return Handle<Map>::cast(result);
877   // Create a new map and add it to the cache.
878   Handle<Map> map =
879       CopyMap(Handle<Map>(context->object_function()->initial_map()),
880               keys->length());
881   AddToMapCache(context, keys, map);
882   return Handle<Map>(map);
883 }
884 
885 
SetRegExpAtomData(Handle<JSRegExp> regexp,JSRegExp::Type type,Handle<String> source,JSRegExp::Flags flags,Handle<Object> data)886 void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp,
887                                 JSRegExp::Type type,
888                                 Handle<String> source,
889                                 JSRegExp::Flags flags,
890                                 Handle<Object> data) {
891   Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize);
892 
893   store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
894   store->set(JSRegExp::kSourceIndex, *source);
895   store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value()));
896   store->set(JSRegExp::kAtomPatternIndex, *data);
897   regexp->set_data(*store);
898 }
899 
SetRegExpIrregexpData(Handle<JSRegExp> regexp,JSRegExp::Type type,Handle<String> source,JSRegExp::Flags flags,int capture_count)900 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
901                                     JSRegExp::Type type,
902                                     Handle<String> source,
903                                     JSRegExp::Flags flags,
904                                     int capture_count) {
905   Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize);
906 
907   store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
908   store->set(JSRegExp::kSourceIndex, *source);
909   store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value()));
910   store->set(JSRegExp::kIrregexpASCIICodeIndex, Heap::the_hole_value());
911   store->set(JSRegExp::kIrregexpUC16CodeIndex, Heap::the_hole_value());
912   store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0));
913   store->set(JSRegExp::kIrregexpCaptureCountIndex,
914              Smi::FromInt(capture_count));
915   regexp->set_data(*store);
916 }
917 
918 
919 
ConfigureInstance(Handle<FunctionTemplateInfo> desc,Handle<JSObject> instance,bool * pending_exception)920 void Factory::ConfigureInstance(Handle<FunctionTemplateInfo> desc,
921                                 Handle<JSObject> instance,
922                                 bool* pending_exception) {
923   // Configure the instance by adding the properties specified by the
924   // instance template.
925   Handle<Object> instance_template = Handle<Object>(desc->instance_template());
926   if (!instance_template->IsUndefined()) {
927     Execution::ConfigureInstance(instance,
928                                  instance_template,
929                                  pending_exception);
930   } else {
931     *pending_exception = false;
932   }
933 }
934 
935 
936 } }  // namespace v8::internal
937