blob: 83af447d918811456094b1a261e95fe4168ab0dc [file] [log] [blame]
Ben Murdochb0fe1622011-05-05 13:52:32 +01001// Copyright 2010 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// 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"
Ben Murdochb0fe1622011-05-05 13:52:32 +010035#include "objects.h"
Iain Merrick75681382010-08-19 15:07:18 +010036#include "objects-visiting.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000037
38namespace v8 {
39namespace internal {
40
41
42Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) {
43 ASSERT(0 <= size);
44 CALL_HEAP_FUNCTION(Heap::AllocateFixedArray(size, pretenure), FixedArray);
45}
46
47
Steve Block6ded16b2010-05-10 14:33:55 +010048Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size,
49 PretenureFlag pretenure) {
Steve Blocka7e24c12009-10-30 11:49:00 +000050 ASSERT(0 <= size);
Steve Block6ded16b2010-05-10 14:33:55 +010051 CALL_HEAP_FUNCTION(Heap::AllocateFixedArrayWithHoles(size, pretenure),
52 FixedArray);
Steve Blocka7e24c12009-10-30 11:49:00 +000053}
54
55
56Handle<StringDictionary> Factory::NewStringDictionary(int at_least_space_for) {
57 ASSERT(0 <= at_least_space_for);
58 CALL_HEAP_FUNCTION(StringDictionary::Allocate(at_least_space_for),
59 StringDictionary);
60}
61
62
63Handle<NumberDictionary> Factory::NewNumberDictionary(int at_least_space_for) {
64 ASSERT(0 <= at_least_space_for);
65 CALL_HEAP_FUNCTION(NumberDictionary::Allocate(at_least_space_for),
66 NumberDictionary);
67}
68
69
70Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors) {
71 ASSERT(0 <= number_of_descriptors);
72 CALL_HEAP_FUNCTION(DescriptorArray::Allocate(number_of_descriptors),
73 DescriptorArray);
74}
75
76
Ben Murdochb0fe1622011-05-05 13:52:32 +010077Handle<DeoptimizationInputData> Factory::NewDeoptimizationInputData(
78 int deopt_entry_count,
79 PretenureFlag pretenure) {
80 ASSERT(deopt_entry_count > 0);
81 CALL_HEAP_FUNCTION(DeoptimizationInputData::Allocate(deopt_entry_count,
82 pretenure),
83 DeoptimizationInputData);
84}
85
86
87Handle<DeoptimizationOutputData> Factory::NewDeoptimizationOutputData(
88 int deopt_entry_count,
89 PretenureFlag pretenure) {
90 ASSERT(deopt_entry_count > 0);
91 CALL_HEAP_FUNCTION(DeoptimizationOutputData::Allocate(deopt_entry_count,
92 pretenure),
93 DeoptimizationOutputData);
94}
95
96
Steve Blocka7e24c12009-10-30 11:49:00 +000097// Symbols are created in the old generation (data space).
98Handle<String> Factory::LookupSymbol(Vector<const char> string) {
99 CALL_HEAP_FUNCTION(Heap::LookupSymbol(string), String);
100}
101
102
103Handle<String> Factory::NewStringFromAscii(Vector<const char> string,
104 PretenureFlag pretenure) {
105 CALL_HEAP_FUNCTION(Heap::AllocateStringFromAscii(string, pretenure), String);
106}
107
108Handle<String> Factory::NewStringFromUtf8(Vector<const char> string,
109 PretenureFlag pretenure) {
110 CALL_HEAP_FUNCTION(Heap::AllocateStringFromUtf8(string, pretenure), String);
111}
112
113
114Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
115 PretenureFlag pretenure) {
116 CALL_HEAP_FUNCTION(Heap::AllocateStringFromTwoByte(string, pretenure),
117 String);
118}
119
120
Leon Clarkeac952652010-07-15 11:15:24 +0100121Handle<String> Factory::NewRawAsciiString(int length,
122 PretenureFlag pretenure) {
123 CALL_HEAP_FUNCTION(Heap::AllocateRawAsciiString(length, pretenure), String);
124}
125
126
Steve Blocka7e24c12009-10-30 11:49:00 +0000127Handle<String> Factory::NewRawTwoByteString(int length,
128 PretenureFlag pretenure) {
129 CALL_HEAP_FUNCTION(Heap::AllocateRawTwoByteString(length, pretenure), String);
130}
131
132
133Handle<String> Factory::NewConsString(Handle<String> first,
134 Handle<String> second) {
135 CALL_HEAP_FUNCTION(Heap::AllocateConsString(*first, *second), String);
136}
137
138
Steve Blockd0582a62009-12-15 09:54:21 +0000139Handle<String> Factory::NewSubString(Handle<String> str,
140 int begin,
141 int end) {
142 CALL_HEAP_FUNCTION(str->SubString(begin, end), String);
Steve Blocka7e24c12009-10-30 11:49:00 +0000143}
144
145
146Handle<String> Factory::NewExternalStringFromAscii(
147 ExternalAsciiString::Resource* resource) {
148 CALL_HEAP_FUNCTION(Heap::AllocateExternalStringFromAscii(resource), String);
149}
150
151
152Handle<String> Factory::NewExternalStringFromTwoByte(
153 ExternalTwoByteString::Resource* resource) {
154 CALL_HEAP_FUNCTION(Heap::AllocateExternalStringFromTwoByte(resource), String);
155}
156
157
158Handle<Context> Factory::NewGlobalContext() {
159 CALL_HEAP_FUNCTION(Heap::AllocateGlobalContext(), Context);
160}
161
162
163Handle<Context> Factory::NewFunctionContext(int length,
164 Handle<JSFunction> closure) {
165 CALL_HEAP_FUNCTION(Heap::AllocateFunctionContext(length, *closure), Context);
166}
167
168
169Handle<Context> Factory::NewWithContext(Handle<Context> previous,
170 Handle<JSObject> extension,
171 bool is_catch_context) {
172 CALL_HEAP_FUNCTION(Heap::AllocateWithContext(*previous,
173 *extension,
174 is_catch_context),
175 Context);
176}
177
178
179Handle<Struct> Factory::NewStruct(InstanceType type) {
180 CALL_HEAP_FUNCTION(Heap::AllocateStruct(type), Struct);
181}
182
183
184Handle<AccessorInfo> Factory::NewAccessorInfo() {
185 Handle<AccessorInfo> info =
186 Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE));
187 info->set_flag(0); // Must clear the flag, it was initialized as undefined.
188 return info;
189}
190
191
192Handle<Script> Factory::NewScript(Handle<String> source) {
193 // Generate id for this script.
194 int id;
195 if (Heap::last_script_id()->IsUndefined()) {
196 // Script ids start from one.
197 id = 1;
198 } else {
199 // Increment id, wrap when positive smi is exhausted.
200 id = Smi::cast(Heap::last_script_id())->value();
201 id++;
202 if (!Smi::IsValid(id)) {
203 id = 0;
204 }
205 }
206 Heap::SetLastScriptId(Smi::FromInt(id));
207
208 // Create and initialize script object.
209 Handle<Proxy> wrapper = Factory::NewProxy(0, TENURED);
210 Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
211 script->set_source(*source);
212 script->set_name(Heap::undefined_value());
213 script->set_id(Heap::last_script_id());
214 script->set_line_offset(Smi::FromInt(0));
215 script->set_column_offset(Smi::FromInt(0));
216 script->set_data(Heap::undefined_value());
217 script->set_context_data(Heap::undefined_value());
218 script->set_type(Smi::FromInt(Script::TYPE_NORMAL));
219 script->set_compilation_type(Smi::FromInt(Script::COMPILATION_TYPE_HOST));
220 script->set_wrapper(*wrapper);
221 script->set_line_ends(Heap::undefined_value());
Steve Blockd0582a62009-12-15 09:54:21 +0000222 script->set_eval_from_shared(Heap::undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000223 script->set_eval_from_instructions_offset(Smi::FromInt(0));
224
225 return script;
226}
227
228
229Handle<Proxy> Factory::NewProxy(Address addr, PretenureFlag pretenure) {
230 CALL_HEAP_FUNCTION(Heap::AllocateProxy(addr, pretenure), Proxy);
231}
232
233
234Handle<Proxy> Factory::NewProxy(const AccessorDescriptor* desc) {
235 return NewProxy((Address) desc, TENURED);
236}
237
238
239Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) {
240 ASSERT(0 <= length);
241 CALL_HEAP_FUNCTION(Heap::AllocateByteArray(length, pretenure), ByteArray);
242}
243
244
245Handle<PixelArray> Factory::NewPixelArray(int length,
246 uint8_t* external_pointer,
247 PretenureFlag pretenure) {
248 ASSERT(0 <= length);
249 CALL_HEAP_FUNCTION(Heap::AllocatePixelArray(length,
250 external_pointer,
251 pretenure), PixelArray);
252}
253
254
Steve Block3ce2e202009-11-05 08:53:23 +0000255Handle<ExternalArray> Factory::NewExternalArray(int length,
256 ExternalArrayType array_type,
257 void* external_pointer,
258 PretenureFlag pretenure) {
259 ASSERT(0 <= length);
260 CALL_HEAP_FUNCTION(Heap::AllocateExternalArray(length,
261 array_type,
262 external_pointer,
263 pretenure), ExternalArray);
264}
265
266
Ben Murdochb0fe1622011-05-05 13:52:32 +0100267Handle<JSGlobalPropertyCell> Factory::NewJSGlobalPropertyCell(
268 Handle<Object> value) {
269 CALL_HEAP_FUNCTION(Heap::AllocateJSGlobalPropertyCell(*value),
270 JSGlobalPropertyCell);
271}
272
273
Steve Blocka7e24c12009-10-30 11:49:00 +0000274Handle<Map> Factory::NewMap(InstanceType type, int instance_size) {
275 CALL_HEAP_FUNCTION(Heap::AllocateMap(type, instance_size), Map);
276}
277
278
279Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
280 CALL_HEAP_FUNCTION(Heap::AllocateFunctionPrototype(*function), JSObject);
281}
282
283
284Handle<Map> Factory::CopyMapDropDescriptors(Handle<Map> src) {
285 CALL_HEAP_FUNCTION(src->CopyDropDescriptors(), Map);
286}
287
288
289Handle<Map> Factory::CopyMap(Handle<Map> src,
290 int extra_inobject_properties) {
291 Handle<Map> copy = CopyMapDropDescriptors(src);
292 // Check that we do not overflow the instance size when adding the
293 // extra inobject properties.
294 int instance_size_delta = extra_inobject_properties * kPointerSize;
295 int max_instance_size_delta =
296 JSObject::kMaxInstanceSize - copy->instance_size();
297 if (instance_size_delta > max_instance_size_delta) {
298 // If the instance size overflows, we allocate as many properties
299 // as we can as inobject properties.
300 instance_size_delta = max_instance_size_delta;
301 extra_inobject_properties = max_instance_size_delta >> kPointerSizeLog2;
302 }
303 // Adjust the map with the extra inobject properties.
304 int inobject_properties =
305 copy->inobject_properties() + extra_inobject_properties;
306 copy->set_inobject_properties(inobject_properties);
307 copy->set_unused_property_fields(inobject_properties);
308 copy->set_instance_size(copy->instance_size() + instance_size_delta);
Iain Merrick75681382010-08-19 15:07:18 +0100309 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy));
Steve Blocka7e24c12009-10-30 11:49:00 +0000310 return copy;
311}
312
Steve Block8defd9f2010-07-08 12:39:36 +0100313
Steve Blocka7e24c12009-10-30 11:49:00 +0000314Handle<Map> Factory::CopyMapDropTransitions(Handle<Map> src) {
315 CALL_HEAP_FUNCTION(src->CopyDropTransitions(), Map);
316}
317
318
Steve Block8defd9f2010-07-08 12:39:36 +0100319Handle<Map> Factory::GetFastElementsMap(Handle<Map> src) {
320 CALL_HEAP_FUNCTION(src->GetFastElementsMap(), Map);
321}
322
323
324Handle<Map> Factory::GetSlowElementsMap(Handle<Map> src) {
325 CALL_HEAP_FUNCTION(src->GetSlowElementsMap(), Map);
326}
327
328
Steve Blocka7e24c12009-10-30 11:49:00 +0000329Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
330 CALL_HEAP_FUNCTION(array->Copy(), FixedArray);
331}
332
333
Steve Block6ded16b2010-05-10 14:33:55 +0100334Handle<JSFunction> Factory::BaseNewFunctionFromSharedFunctionInfo(
335 Handle<SharedFunctionInfo> function_info,
Leon Clarkee46be812010-01-19 14:06:41 +0000336 Handle<Map> function_map,
337 PretenureFlag pretenure) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000338 CALL_HEAP_FUNCTION(Heap::AllocateFunction(*function_map,
Steve Block6ded16b2010-05-10 14:33:55 +0100339 *function_info,
Leon Clarkee46be812010-01-19 14:06:41 +0000340 Heap::the_hole_value(),
341 pretenure),
Steve Blocka7e24c12009-10-30 11:49:00 +0000342 JSFunction);
343}
344
345
Steve Block6ded16b2010-05-10 14:33:55 +0100346Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
347 Handle<SharedFunctionInfo> function_info,
Leon Clarkee46be812010-01-19 14:06:41 +0000348 Handle<Context> context,
349 PretenureFlag pretenure) {
Steve Block6ded16b2010-05-10 14:33:55 +0100350 Handle<JSFunction> result = BaseNewFunctionFromSharedFunctionInfo(
351 function_info, Top::function_map(), pretenure);
Steve Blocka7e24c12009-10-30 11:49:00 +0000352 result->set_context(*context);
Steve Block6ded16b2010-05-10 14:33:55 +0100353 int number_of_literals = function_info->num_literals();
Steve Blocka7e24c12009-10-30 11:49:00 +0000354 Handle<FixedArray> literals =
Leon Clarkee46be812010-01-19 14:06:41 +0000355 Factory::NewFixedArray(number_of_literals, pretenure);
Steve Blocka7e24c12009-10-30 11:49:00 +0000356 if (number_of_literals > 0) {
357 // Store the object, regexp and array functions in the literals
358 // array prefix. These functions will be used when creating
359 // object, regexp and array literals in this function.
360 literals->set(JSFunction::kLiteralGlobalContextIndex,
361 context->global_context());
362 }
363 result->set_literals(*literals);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100364 result->set_next_function_link(Heap::undefined_value());
365
366 if (V8::UseCrankshaft() &&
367 FLAG_always_opt &&
368 result->is_compiled() &&
369 !function_info->is_toplevel() &&
370 function_info->allows_lazy_compilation()) {
371 result->MarkForLazyRecompilation();
372 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000373 return result;
374}
375
376
377Handle<Object> Factory::NewNumber(double value,
378 PretenureFlag pretenure) {
379 CALL_HEAP_FUNCTION(Heap::NumberFromDouble(value, pretenure), Object);
380}
381
382
383Handle<Object> Factory::NewNumberFromInt(int value) {
384 CALL_HEAP_FUNCTION(Heap::NumberFromInt32(value), Object);
385}
386
387
388Handle<Object> Factory::NewNumberFromUint(uint32_t value) {
389 CALL_HEAP_FUNCTION(Heap::NumberFromUint32(value), Object);
390}
391
392
393Handle<JSObject> Factory::NewNeanderObject() {
394 CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(Heap::neander_map()),
395 JSObject);
396}
397
398
399Handle<Object> Factory::NewTypeError(const char* type,
400 Vector< Handle<Object> > args) {
401 return NewError("MakeTypeError", type, args);
402}
403
404
405Handle<Object> Factory::NewTypeError(Handle<String> message) {
406 return NewError("$TypeError", message);
407}
408
409
410Handle<Object> Factory::NewRangeError(const char* type,
411 Vector< Handle<Object> > args) {
412 return NewError("MakeRangeError", type, args);
413}
414
415
416Handle<Object> Factory::NewRangeError(Handle<String> message) {
417 return NewError("$RangeError", message);
418}
419
420
421Handle<Object> Factory::NewSyntaxError(const char* type, Handle<JSArray> args) {
422 return NewError("MakeSyntaxError", type, args);
423}
424
425
426Handle<Object> Factory::NewSyntaxError(Handle<String> message) {
427 return NewError("$SyntaxError", message);
428}
429
430
431Handle<Object> Factory::NewReferenceError(const char* type,
432 Vector< Handle<Object> > args) {
433 return NewError("MakeReferenceError", type, args);
434}
435
436
437Handle<Object> Factory::NewReferenceError(Handle<String> message) {
438 return NewError("$ReferenceError", message);
439}
440
441
442Handle<Object> Factory::NewError(const char* maker, const char* type,
443 Vector< Handle<Object> > args) {
444 v8::HandleScope scope; // Instantiate a closeable HandleScope for EscapeFrom.
445 Handle<FixedArray> array = Factory::NewFixedArray(args.length());
446 for (int i = 0; i < args.length(); i++) {
447 array->set(i, *args[i]);
448 }
449 Handle<JSArray> object = Factory::NewJSArrayWithElements(array);
450 Handle<Object> result = NewError(maker, type, object);
451 return result.EscapeFrom(&scope);
452}
453
454
455Handle<Object> Factory::NewEvalError(const char* type,
456 Vector< Handle<Object> > args) {
457 return NewError("MakeEvalError", type, args);
458}
459
460
461Handle<Object> Factory::NewError(const char* type,
462 Vector< Handle<Object> > args) {
463 return NewError("MakeError", type, args);
464}
465
466
467Handle<Object> Factory::NewError(const char* maker,
468 const char* type,
469 Handle<JSArray> args) {
470 Handle<String> make_str = Factory::LookupAsciiSymbol(maker);
John Reck59135872010-11-02 12:39:01 -0700471 Handle<Object> fun_obj(Top::builtins()->GetPropertyNoExceptionThrown(
472 *make_str));
Steve Blocka7e24c12009-10-30 11:49:00 +0000473 // If the builtins haven't been properly configured yet this error
474 // constructor may not have been defined. Bail out.
475 if (!fun_obj->IsJSFunction())
476 return Factory::undefined_value();
477 Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
478 Handle<Object> type_obj = Factory::LookupAsciiSymbol(type);
479 Object** argv[2] = { type_obj.location(),
480 Handle<Object>::cast(args).location() };
481
482 // Invoke the JavaScript factory method. If an exception is thrown while
483 // running the factory method, use the exception as the result.
484 bool caught_exception;
485 Handle<Object> result = Execution::TryCall(fun,
486 Top::builtins(),
487 2,
488 argv,
489 &caught_exception);
490 return result;
491}
492
493
494Handle<Object> Factory::NewError(Handle<String> message) {
495 return NewError("$Error", message);
496}
497
498
499Handle<Object> Factory::NewError(const char* constructor,
500 Handle<String> message) {
501 Handle<String> constr = Factory::LookupAsciiSymbol(constructor);
502 Handle<JSFunction> fun =
503 Handle<JSFunction>(
504 JSFunction::cast(
John Reck59135872010-11-02 12:39:01 -0700505 Top::builtins()->GetPropertyNoExceptionThrown(*constr)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000506 Object** argv[1] = { Handle<Object>::cast(message).location() };
507
508 // Invoke the JavaScript factory method. If an exception is thrown while
509 // running the factory method, use the exception as the result.
510 bool caught_exception;
511 Handle<Object> result = Execution::TryCall(fun,
512 Top::builtins(),
513 1,
514 argv,
515 &caught_exception);
516 return result;
517}
518
519
520Handle<JSFunction> Factory::NewFunction(Handle<String> name,
521 InstanceType type,
522 int instance_size,
523 Handle<Code> code,
524 bool force_initial_map) {
525 // Allocate the function
526 Handle<JSFunction> function = NewFunction(name, the_hole_value());
Iain Merrick75681382010-08-19 15:07:18 +0100527
528 // Setup the code pointer in both the shared function info and in
529 // the function itself.
530 function->shared()->set_code(*code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000531 function->set_code(*code);
532
533 if (force_initial_map ||
534 type != JS_OBJECT_TYPE ||
535 instance_size != JSObject::kHeaderSize) {
536 Handle<Map> initial_map = NewMap(type, instance_size);
537 Handle<JSObject> prototype = NewFunctionPrototype(function);
538 initial_map->set_prototype(*prototype);
539 function->set_initial_map(*initial_map);
540 initial_map->set_constructor(*function);
541 } else {
542 ASSERT(!function->has_initial_map());
543 ASSERT(!function->has_prototype());
544 }
545
546 return function;
547}
548
549
Steve Blocka7e24c12009-10-30 11:49:00 +0000550Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
551 InstanceType type,
552 int instance_size,
553 Handle<JSObject> prototype,
554 Handle<Code> code,
555 bool force_initial_map) {
Iain Merrick75681382010-08-19 15:07:18 +0100556 // Allocate the function.
Steve Blocka7e24c12009-10-30 11:49:00 +0000557 Handle<JSFunction> function = NewFunction(name, prototype);
558
Iain Merrick75681382010-08-19 15:07:18 +0100559 // Setup the code pointer in both the shared function info and in
560 // the function itself.
561 function->shared()->set_code(*code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000562 function->set_code(*code);
563
564 if (force_initial_map ||
565 type != JS_OBJECT_TYPE ||
566 instance_size != JSObject::kHeaderSize) {
567 Handle<Map> initial_map = NewMap(type, instance_size);
568 function->set_initial_map(*initial_map);
569 initial_map->set_constructor(*function);
570 }
571
572 // Set function.prototype and give the prototype a constructor
573 // property that refers to the function.
574 SetPrototypeProperty(function, prototype);
575 SetProperty(prototype, Factory::constructor_symbol(), function, DONT_ENUM);
576 return function;
577}
578
579
Steve Block6ded16b2010-05-10 14:33:55 +0100580Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
581 Handle<Code> code) {
582 Handle<JSFunction> function = NewFunctionWithoutPrototype(name);
Iain Merrick75681382010-08-19 15:07:18 +0100583 function->shared()->set_code(*code);
Steve Block6ded16b2010-05-10 14:33:55 +0100584 function->set_code(*code);
585 ASSERT(!function->has_initial_map());
586 ASSERT(!function->has_prototype());
587 return function;
588}
589
590
Steve Blocka7e24c12009-10-30 11:49:00 +0000591Handle<Code> Factory::NewCode(const CodeDesc& desc,
Steve Blocka7e24c12009-10-30 11:49:00 +0000592 Code::Flags flags,
593 Handle<Object> self_ref) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100594 CALL_HEAP_FUNCTION(Heap::CreateCode(desc, flags, self_ref), Code);
Steve Blocka7e24c12009-10-30 11:49:00 +0000595}
596
597
598Handle<Code> Factory::CopyCode(Handle<Code> code) {
599 CALL_HEAP_FUNCTION(Heap::CopyCode(*code), Code);
600}
601
602
Steve Block6ded16b2010-05-10 14:33:55 +0100603Handle<Code> Factory::CopyCode(Handle<Code> code, Vector<byte> reloc_info) {
604 CALL_HEAP_FUNCTION(Heap::CopyCode(*code, reloc_info), Code);
605}
606
607
John Reck59135872010-11-02 12:39:01 -0700608MUST_USE_RESULT static inline MaybeObject* DoCopyInsert(
609 DescriptorArray* array,
610 String* key,
611 Object* value,
612 PropertyAttributes attributes) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000613 CallbacksDescriptor desc(key, value, attributes);
John Reck59135872010-11-02 12:39:01 -0700614 MaybeObject* obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS);
Steve Blocka7e24c12009-10-30 11:49:00 +0000615 return obj;
616}
617
618
619// Allocate the new array.
620Handle<DescriptorArray> Factory::CopyAppendProxyDescriptor(
621 Handle<DescriptorArray> array,
622 Handle<String> key,
623 Handle<Object> value,
624 PropertyAttributes attributes) {
625 CALL_HEAP_FUNCTION(DoCopyInsert(*array, *key, *value, attributes),
626 DescriptorArray);
627}
628
629
630Handle<String> Factory::SymbolFromString(Handle<String> value) {
631 CALL_HEAP_FUNCTION(Heap::LookupSymbol(*value), String);
632}
633
634
635Handle<DescriptorArray> Factory::CopyAppendCallbackDescriptors(
636 Handle<DescriptorArray> array,
637 Handle<Object> descriptors) {
638 v8::NeanderArray callbacks(descriptors);
639 int nof_callbacks = callbacks.length();
640 Handle<DescriptorArray> result =
641 NewDescriptorArray(array->number_of_descriptors() + nof_callbacks);
642
643 // Number of descriptors added to the result so far.
644 int descriptor_count = 0;
645
646 // Copy the descriptors from the array.
647 for (int i = 0; i < array->number_of_descriptors(); i++) {
648 if (array->GetType(i) != NULL_DESCRIPTOR) {
649 result->CopyFrom(descriptor_count++, *array, i);
650 }
651 }
652
653 // Number of duplicates detected.
654 int duplicates = 0;
655
656 // Fill in new callback descriptors. Process the callbacks from
657 // back to front so that the last callback with a given name takes
658 // precedence over previously added callbacks with that name.
659 for (int i = nof_callbacks - 1; i >= 0; i--) {
660 Handle<AccessorInfo> entry =
661 Handle<AccessorInfo>(AccessorInfo::cast(callbacks.get(i)));
662 // Ensure the key is a symbol before writing into the instance descriptor.
663 Handle<String> key =
664 SymbolFromString(Handle<String>(String::cast(entry->name())));
665 // Check if a descriptor with this name already exists before writing.
666 if (result->LinearSearch(*key, descriptor_count) ==
667 DescriptorArray::kNotFound) {
668 CallbacksDescriptor desc(*key, *entry, entry->property_attributes());
669 result->Set(descriptor_count, &desc);
670 descriptor_count++;
671 } else {
672 duplicates++;
673 }
674 }
675
676 // If duplicates were detected, allocate a result of the right size
677 // and transfer the elements.
678 if (duplicates > 0) {
679 int number_of_descriptors = result->number_of_descriptors() - duplicates;
680 Handle<DescriptorArray> new_result =
681 NewDescriptorArray(number_of_descriptors);
682 for (int i = 0; i < number_of_descriptors; i++) {
683 new_result->CopyFrom(i, *result, i);
684 }
685 result = new_result;
686 }
687
688 // Sort the result before returning.
689 result->Sort();
690 return result;
691}
692
693
694Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
695 PretenureFlag pretenure) {
696 CALL_HEAP_FUNCTION(Heap::AllocateJSObject(*constructor, pretenure), JSObject);
697}
698
699
700Handle<GlobalObject> Factory::NewGlobalObject(
701 Handle<JSFunction> constructor) {
702 CALL_HEAP_FUNCTION(Heap::AllocateGlobalObject(*constructor),
703 GlobalObject);
704}
705
706
707
708Handle<JSObject> Factory::NewJSObjectFromMap(Handle<Map> map) {
709 CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(*map, NOT_TENURED),
710 JSObject);
711}
712
713
714Handle<JSArray> Factory::NewJSArray(int length,
715 PretenureFlag pretenure) {
716 Handle<JSObject> obj = NewJSObject(Top::array_function(), pretenure);
717 CALL_HEAP_FUNCTION(Handle<JSArray>::cast(obj)->Initialize(length), JSArray);
718}
719
720
721Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArray> elements,
722 PretenureFlag pretenure) {
723 Handle<JSArray> result =
724 Handle<JSArray>::cast(NewJSObject(Top::array_function(), pretenure));
725 result->SetContent(*elements);
726 return result;
727}
728
729
Steve Block6ded16b2010-05-10 14:33:55 +0100730Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100731 Handle<String> name,
732 int number_of_literals,
733 Handle<Code> code,
734 Handle<SerializedScopeInfo> scope_info) {
Steve Block6ded16b2010-05-10 14:33:55 +0100735 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
736 shared->set_code(*code);
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100737 shared->set_scope_info(*scope_info);
Steve Block6ded16b2010-05-10 14:33:55 +0100738 int literals_array_size = number_of_literals;
739 // If the function contains object, regexp or array literals,
740 // allocate extra space for a literals array prefix containing the
741 // context.
742 if (number_of_literals > 0) {
743 literals_array_size += JSFunction::kLiteralsPrefixSize;
744 }
745 shared->set_num_literals(literals_array_size);
746 return shared;
747}
748
749
Steve Blocka7e24c12009-10-30 11:49:00 +0000750Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) {
751 CALL_HEAP_FUNCTION(Heap::AllocateSharedFunctionInfo(*name),
752 SharedFunctionInfo);
753}
754
755
756Handle<String> Factory::NumberToString(Handle<Object> number) {
757 CALL_HEAP_FUNCTION(Heap::NumberToString(*number), String);
758}
759
760
761Handle<NumberDictionary> Factory::DictionaryAtNumberPut(
762 Handle<NumberDictionary> dictionary,
763 uint32_t key,
764 Handle<Object> value) {
765 CALL_HEAP_FUNCTION(dictionary->AtNumberPut(key, *value), NumberDictionary);
766}
767
768
769Handle<JSFunction> Factory::NewFunctionHelper(Handle<String> name,
770 Handle<Object> prototype) {
771 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
772 CALL_HEAP_FUNCTION(Heap::AllocateFunction(*Top::function_map(),
773 *function_share,
774 *prototype),
775 JSFunction);
776}
777
778
779Handle<JSFunction> Factory::NewFunction(Handle<String> name,
780 Handle<Object> prototype) {
781 Handle<JSFunction> fun = NewFunctionHelper(name, prototype);
782 fun->set_context(Top::context()->global_context());
783 return fun;
784}
785
786
Steve Block6ded16b2010-05-10 14:33:55 +0100787Handle<JSFunction> Factory::NewFunctionWithoutPrototypeHelper(
788 Handle<String> name) {
789 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
790 CALL_HEAP_FUNCTION(Heap::AllocateFunction(
791 *Top::function_without_prototype_map(),
792 *function_share,
793 *the_hole_value()),
794 JSFunction);
795}
796
797
798Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name) {
799 Handle<JSFunction> fun = NewFunctionWithoutPrototypeHelper(name);
800 fun->set_context(Top::context()->global_context());
801 return fun;
802}
803
804
Leon Clarkee46be812010-01-19 14:06:41 +0000805Handle<Object> Factory::ToObject(Handle<Object> object) {
806 CALL_HEAP_FUNCTION(object->ToObject(), Object);
807}
808
809
Steve Blocka7e24c12009-10-30 11:49:00 +0000810Handle<Object> Factory::ToObject(Handle<Object> object,
811 Handle<Context> global_context) {
812 CALL_HEAP_FUNCTION(object->ToObject(*global_context), Object);
813}
814
815
816#ifdef ENABLE_DEBUGGER_SUPPORT
817Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
818 // Get the original code of the function.
819 Handle<Code> code(shared->code());
820
821 // Create a copy of the code before allocating the debug info object to avoid
822 // allocation while setting up the debug info object.
823 Handle<Code> original_code(*Factory::CopyCode(code));
824
825 // Allocate initial fixed array for active break points before allocating the
826 // debug info object to avoid allocation while setting up the debug info
827 // object.
828 Handle<FixedArray> break_points(
829 Factory::NewFixedArray(Debug::kEstimatedNofBreakPointsInFunction));
830
831 // Create and set up the debug info object. Debug info contains function, a
832 // copy of the original code, the executing code and initial fixed array for
833 // active break points.
834 Handle<DebugInfo> debug_info =
835 Handle<DebugInfo>::cast(Factory::NewStruct(DEBUG_INFO_TYPE));
836 debug_info->set_shared(*shared);
837 debug_info->set_original_code(*original_code);
838 debug_info->set_code(*code);
839 debug_info->set_break_points(*break_points);
840
841 // Link debug info to function.
842 shared->set_debug_info(*debug_info);
843
844 return debug_info;
845}
846#endif
847
848
849Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee,
850 int length) {
851 CALL_HEAP_FUNCTION(Heap::AllocateArgumentsObject(*callee, length), JSObject);
852}
853
854
855Handle<JSFunction> Factory::CreateApiFunction(
856 Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) {
857 Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::HandleApiCall));
Leon Clarkee46be812010-01-19 14:06:41 +0000858 Handle<Code> construct_stub =
859 Handle<Code>(Builtins::builtin(Builtins::JSConstructStubApi));
Steve Blocka7e24c12009-10-30 11:49:00 +0000860
861 int internal_field_count = 0;
862 if (!obj->instance_template()->IsUndefined()) {
863 Handle<ObjectTemplateInfo> instance_template =
864 Handle<ObjectTemplateInfo>(
865 ObjectTemplateInfo::cast(obj->instance_template()));
866 internal_field_count =
867 Smi::cast(instance_template->internal_field_count())->value();
868 }
869
870 int instance_size = kPointerSize * internal_field_count;
871 InstanceType type = INVALID_TYPE;
872 switch (instance_type) {
873 case JavaScriptObject:
874 type = JS_OBJECT_TYPE;
875 instance_size += JSObject::kHeaderSize;
876 break;
877 case InnerGlobalObject:
878 type = JS_GLOBAL_OBJECT_TYPE;
879 instance_size += JSGlobalObject::kSize;
880 break;
881 case OuterGlobalObject:
882 type = JS_GLOBAL_PROXY_TYPE;
883 instance_size += JSGlobalProxy::kSize;
884 break;
885 default:
886 break;
887 }
888 ASSERT(type != INVALID_TYPE);
889
890 Handle<JSFunction> result =
891 Factory::NewFunction(Factory::empty_symbol(),
892 type,
893 instance_size,
894 code,
895 true);
896 // Set class name.
897 Handle<Object> class_name = Handle<Object>(obj->class_name());
898 if (class_name->IsString()) {
899 result->shared()->set_instance_class_name(*class_name);
900 result->shared()->set_name(*class_name);
901 }
902
903 Handle<Map> map = Handle<Map>(result->initial_map());
904
905 // Mark as undetectable if needed.
906 if (obj->undetectable()) {
907 map->set_is_undetectable();
908 }
909
910 // Mark as hidden for the __proto__ accessor if needed.
911 if (obj->hidden_prototype()) {
912 map->set_is_hidden_prototype();
913 }
914
915 // Mark as needs_access_check if needed.
916 if (obj->needs_access_check()) {
917 map->set_is_access_check_needed(true);
918 }
919
920 // Set interceptor information in the map.
921 if (!obj->named_property_handler()->IsUndefined()) {
922 map->set_has_named_interceptor();
923 }
924 if (!obj->indexed_property_handler()->IsUndefined()) {
925 map->set_has_indexed_interceptor();
926 }
927
928 // Set instance call-as-function information in the map.
929 if (!obj->instance_call_handler()->IsUndefined()) {
930 map->set_has_instance_call_handler();
931 }
932
933 result->shared()->set_function_data(*obj);
Leon Clarkee46be812010-01-19 14:06:41 +0000934 result->shared()->set_construct_stub(*construct_stub);
Steve Blocka7e24c12009-10-30 11:49:00 +0000935 result->shared()->DontAdaptArguments();
936
937 // Recursively copy parent templates' accessors, 'data' may be modified.
938 Handle<DescriptorArray> array =
939 Handle<DescriptorArray>(map->instance_descriptors());
940 while (true) {
941 Handle<Object> props = Handle<Object>(obj->property_accessors());
942 if (!props->IsUndefined()) {
943 array = Factory::CopyAppendCallbackDescriptors(array, props);
944 }
945 Handle<Object> parent = Handle<Object>(obj->parent_template());
946 if (parent->IsUndefined()) break;
947 obj = Handle<FunctionTemplateInfo>::cast(parent);
948 }
949 if (!array->IsEmpty()) {
950 map->set_instance_descriptors(*array);
951 }
952
Steve Block6ded16b2010-05-10 14:33:55 +0100953 ASSERT(result->shared()->IsApiFunction());
Steve Blocka7e24c12009-10-30 11:49:00 +0000954 return result;
955}
956
957
958Handle<MapCache> Factory::NewMapCache(int at_least_space_for) {
959 CALL_HEAP_FUNCTION(MapCache::Allocate(at_least_space_for), MapCache);
960}
961
962
John Reck59135872010-11-02 12:39:01 -0700963MUST_USE_RESULT static MaybeObject* UpdateMapCacheWith(Context* context,
964 FixedArray* keys,
965 Map* map) {
966 Object* result;
967 { MaybeObject* maybe_result =
968 MapCache::cast(context->map_cache())->Put(keys, map);
969 if (!maybe_result->ToObject(&result)) return maybe_result;
970 }
971 context->set_map_cache(MapCache::cast(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000972 return result;
973}
974
975
976Handle<MapCache> Factory::AddToMapCache(Handle<Context> context,
977 Handle<FixedArray> keys,
978 Handle<Map> map) {
979 CALL_HEAP_FUNCTION(UpdateMapCacheWith(*context, *keys, *map), MapCache);
980}
981
982
983Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
984 Handle<FixedArray> keys) {
985 if (context->map_cache()->IsUndefined()) {
986 // Allocate the new map cache for the global context.
987 Handle<MapCache> new_cache = NewMapCache(24);
988 context->set_map_cache(*new_cache);
989 }
990 // Check to see whether there is a matching element in the cache.
991 Handle<MapCache> cache =
992 Handle<MapCache>(MapCache::cast(context->map_cache()));
993 Handle<Object> result = Handle<Object>(cache->Lookup(*keys));
994 if (result->IsMap()) return Handle<Map>::cast(result);
995 // Create a new map and add it to the cache.
996 Handle<Map> map =
997 CopyMap(Handle<Map>(context->object_function()->initial_map()),
998 keys->length());
999 AddToMapCache(context, keys, map);
1000 return Handle<Map>(map);
1001}
1002
1003
1004void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp,
1005 JSRegExp::Type type,
1006 Handle<String> source,
1007 JSRegExp::Flags flags,
1008 Handle<Object> data) {
1009 Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize);
1010
1011 store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
1012 store->set(JSRegExp::kSourceIndex, *source);
1013 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value()));
1014 store->set(JSRegExp::kAtomPatternIndex, *data);
1015 regexp->set_data(*store);
1016}
1017
1018void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
1019 JSRegExp::Type type,
1020 Handle<String> source,
1021 JSRegExp::Flags flags,
1022 int capture_count) {
1023 Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize);
1024
1025 store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
1026 store->set(JSRegExp::kSourceIndex, *source);
1027 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value()));
1028 store->set(JSRegExp::kIrregexpASCIICodeIndex, Heap::the_hole_value());
1029 store->set(JSRegExp::kIrregexpUC16CodeIndex, Heap::the_hole_value());
1030 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0));
1031 store->set(JSRegExp::kIrregexpCaptureCountIndex,
1032 Smi::FromInt(capture_count));
1033 regexp->set_data(*store);
1034}
1035
1036
1037
1038void Factory::ConfigureInstance(Handle<FunctionTemplateInfo> desc,
1039 Handle<JSObject> instance,
1040 bool* pending_exception) {
1041 // Configure the instance by adding the properties specified by the
1042 // instance template.
1043 Handle<Object> instance_template = Handle<Object>(desc->instance_template());
1044 if (!instance_template->IsUndefined()) {
1045 Execution::ConfigureInstance(instance,
1046 instance_template,
1047 pending_exception);
1048 } else {
1049 *pending_exception = false;
1050 }
1051}
1052
1053
1054} } // namespace v8::internal