blob: 444e7e2cdd4665c35624f574e6bf23e4235935df [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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"
v8.team.kasperl727e9952008-09-02 14:56:44 +000031#include "debug.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000032#include "execution.h"
33#include "factory.h"
34#include "macro-assembler.h"
35
36namespace v8 { namespace internal {
37
38
39Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) {
40 ASSERT(0 <= size);
41 CALL_HEAP_FUNCTION(Heap::AllocateFixedArray(size, pretenure), FixedArray);
42}
43
44
45Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors) {
46 ASSERT(0 <= number_of_descriptors);
47 CALL_HEAP_FUNCTION(DescriptorArray::Allocate(number_of_descriptors),
48 DescriptorArray);
49}
50
51
ager@chromium.org9258b6b2008-09-11 09:11:10 +000052// Symbols are created in the old generation (data space).
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053Handle<String> Factory::LookupSymbol(Vector<const char> string) {
54 CALL_HEAP_FUNCTION(Heap::LookupSymbol(string), String);
55}
56
57
58Handle<String> Factory::NewStringFromAscii(Vector<const char> string,
59 PretenureFlag pretenure) {
60 CALL_HEAP_FUNCTION(Heap::AllocateStringFromAscii(string, pretenure), String);
61}
62
63Handle<String> Factory::NewStringFromUtf8(Vector<const char> string,
64 PretenureFlag pretenure) {
65 CALL_HEAP_FUNCTION(Heap::AllocateStringFromUtf8(string, pretenure), String);
66}
67
68
69Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string) {
70 CALL_HEAP_FUNCTION(Heap::AllocateStringFromTwoByte(string), String);
71}
72
73
74Handle<String> Factory::NewRawTwoByteString(int length,
75 PretenureFlag pretenure) {
76 CALL_HEAP_FUNCTION(Heap::AllocateRawTwoByteString(length, pretenure), String);
77}
78
79
80Handle<String> Factory::NewConsString(Handle<String> first,
81 Handle<String> second) {
82 CALL_HEAP_FUNCTION(Heap::AllocateConsString(*first, *second), String);
83}
84
85
86Handle<String> Factory::NewStringSlice(Handle<String> str, int begin, int end) {
87 CALL_HEAP_FUNCTION(str->Slice(begin, end), String);
88}
89
90
91Handle<String> Factory::NewExternalStringFromAscii(
92 ExternalAsciiString::Resource* resource) {
93 CALL_HEAP_FUNCTION(Heap::AllocateExternalStringFromAscii(resource), String);
94}
95
96
97Handle<String> Factory::NewExternalStringFromTwoByte(
98 ExternalTwoByteString::Resource* resource) {
99 CALL_HEAP_FUNCTION(Heap::AllocateExternalStringFromTwoByte(resource), String);
100}
101
102
103Handle<Context> Factory::NewGlobalContext() {
104 CALL_HEAP_FUNCTION(Heap::AllocateGlobalContext(), Context);
105}
106
107
108Handle<Context> Factory::NewFunctionContext(int length,
109 Handle<JSFunction> closure) {
110 CALL_HEAP_FUNCTION(Heap::AllocateFunctionContext(length, *closure), Context);
111}
112
113
114Handle<Context> Factory::NewWithContext(Handle<Context> previous,
115 Handle<JSObject> extension) {
116 CALL_HEAP_FUNCTION(Heap::AllocateWithContext(*previous, *extension), Context);
117}
118
119
120Handle<Struct> Factory::NewStruct(InstanceType type) {
121 CALL_HEAP_FUNCTION(Heap::AllocateStruct(type), Struct);
122}
123
124
125Handle<AccessorInfo> Factory::NewAccessorInfo() {
126 Handle<AccessorInfo> info =
127 Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE));
128 info->set_flag(0); // Must clear the flag, it was initialized as undefined.
129 return info;
130}
131
132
133Handle<Script> Factory::NewScript(Handle<String> source) {
134 Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
135 script->set_source(*source);
136 script->set_name(Heap::undefined_value());
137 script->set_line_offset(Smi::FromInt(0));
138 script->set_column_offset(Smi::FromInt(0));
139 script->set_wrapper(*Factory::NewProxy(0, TENURED));
140 script->set_type(Smi::FromInt(SCRIPT_TYPE_NORMAL));
141 return script;
142}
143
144
145Handle<Proxy> Factory::NewProxy(Address addr, PretenureFlag pretenure) {
146 CALL_HEAP_FUNCTION(Heap::AllocateProxy(addr, pretenure), Proxy);
147}
148
149
150Handle<Proxy> Factory::NewProxy(const AccessorDescriptor* desc) {
151 return NewProxy((Address) desc, TENURED);
152}
153
154
155Handle<ByteArray> Factory::NewByteArray(int length) {
156 ASSERT(0 <= length);
157 CALL_HEAP_FUNCTION(Heap::AllocateByteArray(length), ByteArray);
158}
159
160
161Handle<Map> Factory::NewMap(InstanceType type, int instance_size) {
162 CALL_HEAP_FUNCTION(Heap::AllocateMap(type, instance_size), Map);
163}
164
165
166Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
167 CALL_HEAP_FUNCTION(Heap::AllocateFunctionPrototype(*function), JSObject);
168}
169
170
171Handle<Map> Factory::CopyMap(Handle<Map> src) {
172 CALL_HEAP_FUNCTION(src->Copy(), Map);
173}
174
175
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000176Handle<Map> Factory::CopyMapDropTransitions(Handle<Map> src) {
177 CALL_HEAP_FUNCTION(src->CopyDropTransitions(), Map);
178}
179
180
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000181Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
182 CALL_HEAP_FUNCTION(array->Copy(), FixedArray);
183}
184
185
186Handle<JSFunction> Factory::BaseNewFunctionFromBoilerplate(
187 Handle<JSFunction> boilerplate,
188 Handle<Map> function_map) {
189 ASSERT(boilerplate->IsBoilerplate());
190 ASSERT(!boilerplate->has_initial_map());
191 ASSERT(!boilerplate->has_prototype());
192 ASSERT(boilerplate->properties() == Heap::empty_fixed_array());
193 ASSERT(boilerplate->elements() == Heap::empty_fixed_array());
194 CALL_HEAP_FUNCTION(Heap::AllocateFunction(*function_map,
195 boilerplate->shared(),
196 Heap::the_hole_value()),
197 JSFunction);
198}
199
200
201Handle<JSFunction> Factory::NewFunctionFromBoilerplate(
202 Handle<JSFunction> boilerplate,
203 Handle<Context> context) {
204 Handle<JSFunction> result =
205 BaseNewFunctionFromBoilerplate(boilerplate, Top::function_map());
206 result->set_context(*context);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000207 int number_of_literals = boilerplate->NumberOfLiterals();
208 Handle<FixedArray> literals =
209 Factory::NewFixedArray(number_of_literals, TENURED);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000210 if (number_of_literals > 0) {
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000211 // Store the object, regexp and array functions in the literals
212 // array prefix. These functions will be used when creating
213 // object, regexp and array literals in this function.
214 literals->set(JSFunction::kLiteralObjectFunctionIndex,
215 context->global_context()->object_function());
216 literals->set(JSFunction::kLiteralRegExpFunctionIndex,
217 context->global_context()->regexp_function());
218 literals->set(JSFunction::kLiteralArrayFunctionIndex,
219 context->global_context()->array_function());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000220 }
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000221 result->set_literals(*literals);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000222 ASSERT(!result->IsBoilerplate());
223 return result;
224}
225
226
227Handle<Object> Factory::NewNumber(double value,
228 PretenureFlag pretenure) {
229 CALL_HEAP_FUNCTION(Heap::NumberFromDouble(value, pretenure), Object);
230}
231
232
233Handle<Object> Factory::NewNumberFromInt(int value) {
234 CALL_HEAP_FUNCTION(Heap::NumberFromInt32(value), Object);
235}
236
237
238Handle<JSObject> Factory::NewNeanderObject() {
239 CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(Heap::neander_map()),
240 JSObject);
241}
242
243
244Handle<Object> Factory::NewTypeError(const char* type,
245 Vector< Handle<Object> > args) {
246 return NewError("MakeTypeError", type, args);
247}
248
249
250Handle<Object> Factory::NewTypeError(Handle<String> message) {
251 return NewError("$TypeError", message);
252}
253
254
255Handle<Object> Factory::NewRangeError(const char* type,
256 Vector< Handle<Object> > args) {
257 return NewError("MakeRangeError", type, args);
258}
259
260
261Handle<Object> Factory::NewRangeError(Handle<String> message) {
262 return NewError("$RangeError", message);
263}
264
265
266Handle<Object> Factory::NewSyntaxError(const char* type, Handle<JSArray> args) {
267 return NewError("MakeSyntaxError", type, args);
268}
269
270
271Handle<Object> Factory::NewSyntaxError(Handle<String> message) {
272 return NewError("$SyntaxError", message);
273}
274
275
276Handle<Object> Factory::NewReferenceError(const char* type,
277 Vector< Handle<Object> > args) {
278 return NewError("MakeReferenceError", type, args);
279}
280
281
282Handle<Object> Factory::NewReferenceError(Handle<String> message) {
283 return NewError("$ReferenceError", message);
284}
285
286
287Handle<Object> Factory::NewError(const char* maker, const char* type,
288 Vector< Handle<Object> > args) {
289 HandleScope scope;
290 Handle<JSArray> array = NewJSArray(args.length());
291 for (int i = 0; i < args.length(); i++)
292 SetElement(array, i, args[i]);
293 Handle<Object> result = NewError(maker, type, array);
294 return result.EscapeFrom(&scope);
295}
296
297
298Handle<Object> Factory::NewEvalError(const char* type,
299 Vector< Handle<Object> > args) {
300 return NewError("MakeEvalError", type, args);
301}
302
303
304Handle<Object> Factory::NewError(const char* type,
305 Vector< Handle<Object> > args) {
306 return NewError("MakeError", type, args);
307}
308
309
310Handle<Object> Factory::NewError(const char* maker,
311 const char* type,
312 Handle<JSArray> args) {
313 Handle<String> make_str = Factory::LookupAsciiSymbol(maker);
314 Handle<JSFunction> fun =
315 Handle<JSFunction>(
316 JSFunction::cast(
317 Top::security_context_builtins()->GetProperty(*make_str)));
318 Handle<Object> type_obj = Factory::LookupAsciiSymbol(type);
319 Object** argv[2] = { type_obj.location(),
320 Handle<Object>::cast(args).location() };
321
322 // Invoke the JavaScript factory method. If an exception is thrown while
323 // running the factory method, use the exception as the result.
324 bool caught_exception;
325 Handle<Object> result = Execution::TryCall(fun,
326 Top::security_context_builtins(),
327 2,
328 argv,
329 &caught_exception);
330 return result;
331}
332
333
334Handle<Object> Factory::NewError(Handle<String> message) {
335 return NewError("$Error", message);
336}
337
338
339Handle<Object> Factory::NewError(const char* constructor,
340 Handle<String> message) {
341 Handle<String> constr = Factory::LookupAsciiSymbol(constructor);
342 Handle<JSFunction> fun =
343 Handle<JSFunction>(
344 JSFunction::cast(
345 Top::security_context_builtins()->GetProperty(*constr)));
346 Object** argv[1] = { Handle<Object>::cast(message).location() };
347
348 // Invoke the JavaScript factory method. If an exception is thrown while
349 // running the factory method, use the exception as the result.
350 bool caught_exception;
351 Handle<Object> result = Execution::TryCall(fun,
352 Top::security_context_builtins(),
353 1,
354 argv,
355 &caught_exception);
356 return result;
357}
358
359
360Handle<JSFunction> Factory::NewFunction(Handle<String> name,
361 InstanceType type,
362 int instance_size,
363 Handle<Code> code,
364 bool force_initial_map) {
365 // Allocate the function
366 Handle<JSFunction> function = NewFunction(name, the_hole_value());
367 function->set_code(*code);
368
369 if (force_initial_map ||
370 type != JS_OBJECT_TYPE ||
371 instance_size != JSObject::kHeaderSize) {
372 Handle<Map> initial_map = NewMap(type, instance_size);
373 Handle<JSObject> prototype = NewFunctionPrototype(function);
374 initial_map->set_prototype(*prototype);
375 function->set_initial_map(*initial_map);
376 initial_map->set_constructor(*function);
377 } else {
378 ASSERT(!function->has_initial_map());
379 ASSERT(!function->has_prototype());
380 }
381
382 return function;
383}
384
385
386Handle<JSFunction> Factory::NewFunctionBoilerplate(Handle<String> name,
387 int number_of_literals,
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000388 bool contains_array_literal,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000389 Handle<Code> code) {
390 Handle<JSFunction> function = NewFunctionBoilerplate(name);
391 function->set_code(*code);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000392 int literals_array_size = number_of_literals;
393 // If the function contains object, regexp or array literals,
394 // allocate extra space for a literals array prefix containing the
395 // object, regexp and array constructor functions.
396 if (number_of_literals > 0 || contains_array_literal) {
397 literals_array_size += JSFunction::kLiteralsPrefixSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000398 }
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000399 Handle<FixedArray> literals =
400 Factory::NewFixedArray(literals_array_size, TENURED);
401 function->set_literals(*literals);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000402 ASSERT(!function->has_initial_map());
403 ASSERT(!function->has_prototype());
404 return function;
405}
406
407
408Handle<JSFunction> Factory::NewFunctionBoilerplate(Handle<String> name) {
409 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
410 CALL_HEAP_FUNCTION(Heap::AllocateFunction(Heap::boilerplate_function_map(),
411 *shared,
412 Heap::the_hole_value()),
413 JSFunction);
414}
415
416
417Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name,
418 InstanceType type,
419 int instance_size,
420 Handle<JSObject> prototype,
421 Handle<Code> code,
422 bool force_initial_map) {
423 // Allocate the function
424 Handle<JSFunction> function = NewFunction(name, prototype);
425
426 function->set_code(*code);
427
428 if (force_initial_map ||
429 type != JS_OBJECT_TYPE ||
430 instance_size != JSObject::kHeaderSize) {
431 Handle<Map> initial_map = NewMap(type, instance_size);
432 function->set_initial_map(*initial_map);
433 initial_map->set_constructor(*function);
434 }
435
436 // Set function.prototype and give the prototype a constructor
437 // property that refers to the function.
438 SetPrototypeProperty(function, prototype);
439 SetProperty(prototype, Factory::constructor_symbol(), function, DONT_ENUM);
440 return function;
441}
442
443Handle<Code> Factory::NewCode(const CodeDesc& desc, ScopeInfo<>* sinfo,
444 Code::Flags flags) {
445 CALL_HEAP_FUNCTION(Heap::CreateCode(desc, sinfo, flags), Code);
446}
447
448
449Handle<Code> Factory::CopyCode(Handle<Code> code) {
450 CALL_HEAP_FUNCTION(Heap::CopyCode(*code), Code);
451}
452
453
454#define CALL_GC(RETRY) \
455 do { \
456 if (!Heap::CollectGarbage(Failure::cast(RETRY)->requested(), \
457 Failure::cast(RETRY)->allocation_space())) { \
458 /* TODO(1181417): Fix this. */ \
459 V8::FatalProcessOutOfMemory("Factory CALL_GC"); \
460 } \
461 } while (false)
462
463
464// Allocate the new array. We cannot use the CALL_HEAP_FUNCTION macro here,
465// because the stack-allocated CallbacksDescriptor instance is not GC safe.
466Handle<DescriptorArray> Factory::CopyAppendProxyDescriptor(
467 Handle<DescriptorArray> array,
468 Handle<String> key,
469 Handle<Object> value,
470 PropertyAttributes attributes) {
471 GC_GREEDY_CHECK();
472 CallbacksDescriptor desc(*key, *value, attributes);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000473 Object* obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000474 if (obj->IsRetryAfterGC()) {
475 CALL_GC(obj);
476 CallbacksDescriptor desc(*key, *value, attributes);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000477 obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000478 if (obj->IsFailure()) {
479 // TODO(1181417): Fix this.
480 V8::FatalProcessOutOfMemory("CopyAppendProxyDescriptor");
481 }
482 }
483 return Handle<DescriptorArray>(DescriptorArray::cast(obj));
484}
485
486#undef CALL_GC
487
488
489Handle<String> Factory::SymbolFromString(Handle<String> value) {
490 CALL_HEAP_FUNCTION(Heap::LookupSymbol(*value), String);
491}
492
493
494Handle<DescriptorArray> Factory::CopyAppendCallbackDescriptors(
495 Handle<DescriptorArray> array,
496 Handle<Object> descriptors) {
497 v8::NeanderArray callbacks(descriptors);
498 int nof_callbacks = callbacks.length();
499 Handle<DescriptorArray> result =
500 NewDescriptorArray(array->number_of_descriptors() + nof_callbacks);
501
502 // Number of descriptors added to the result so far.
503 int descriptor_count = 0;
504
505 // Copy the descriptors from the array.
506 DescriptorWriter w(*result);
507 for (DescriptorReader r(*array); !r.eos(); r.advance()) {
508 w.WriteFrom(&r);
509 descriptor_count++;
510 }
511
512 // Number of duplicates detected.
513 int duplicates = 0;
514
515 // Fill in new callback descriptors. Process the callbacks from
516 // back to front so that the last callback with a given name takes
517 // precedence over previously added callbacks with that name.
518 for (int i = nof_callbacks - 1; i >= 0; i--) {
519 Handle<AccessorInfo> entry =
520 Handle<AccessorInfo>(AccessorInfo::cast(callbacks.get(i)));
521 // Ensure the key is a symbol before writing into the instance descriptor.
522 Handle<String> key =
523 SymbolFromString(Handle<String>(String::cast(entry->name())));
524 // Check if a descriptor with this name already exists before writing.
525 if (result->BinarySearch(*key, 0, descriptor_count - 1) ==
526 DescriptorArray::kNotFound) {
527 CallbacksDescriptor desc(*key, *entry, entry->property_attributes());
528 w.Write(&desc);
529 descriptor_count++;
530 } else {
531 duplicates++;
532 }
533 }
534
535 // If duplicates were detected, allocate a result of the right size
536 // and transfer the elements.
537 if (duplicates > 0) {
538 Handle<DescriptorArray> new_result =
539 NewDescriptorArray(result->number_of_descriptors() - duplicates);
540 DescriptorWriter w(*new_result);
541 DescriptorReader r(*result);
542 while (!w.eos()) {
543 w.WriteFrom(&r);
544 r.advance();
545 }
546 result = new_result;
547 }
548
549 // Sort the result before returning.
550 result->Sort();
551 return result;
552}
553
554
555Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
556 PretenureFlag pretenure) {
557 CALL_HEAP_FUNCTION(Heap::AllocateJSObject(*constructor, pretenure), JSObject);
558}
559
560
561Handle<JSObject> Factory::NewObjectLiteral(int expected_number_of_properties) {
562 Handle<Map> map = Handle<Map>(Top::object_function()->initial_map());
563 map = Factory::CopyMap(map);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000564 map->set_instance_descriptors(Heap::empty_descriptor_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000565 map->set_unused_property_fields(expected_number_of_properties);
566 CALL_HEAP_FUNCTION(Heap::AllocateJSObjectFromMap(*map, TENURED),
567 JSObject);
568}
569
570
571Handle<JSArray> Factory::NewArrayLiteral(int length) {
572 return NewJSArrayWithElements(NewFixedArray(length), TENURED);
573}
574
575
576Handle<JSArray> Factory::NewJSArray(int length,
577 PretenureFlag pretenure) {
578 Handle<JSObject> obj = NewJSObject(Top::array_function(), pretenure);
579 CALL_HEAP_FUNCTION(Handle<JSArray>::cast(obj)->Initialize(length), JSArray);
580}
581
582
583Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArray> elements,
584 PretenureFlag pretenure) {
585 Handle<JSArray> result =
586 Handle<JSArray>::cast(NewJSObject(Top::array_function(), pretenure));
587 result->SetContent(*elements);
588 return result;
589}
590
591
592Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) {
593 CALL_HEAP_FUNCTION(Heap::AllocateSharedFunctionInfo(*name),
594 SharedFunctionInfo);
595}
596
597
598Handle<Dictionary> Factory::DictionaryAtNumberPut(Handle<Dictionary> dictionary,
599 uint32_t key,
600 Handle<Object> value) {
601 CALL_HEAP_FUNCTION(dictionary->AtNumberPut(key, *value), Dictionary);
602}
603
604
605Handle<JSFunction> Factory::NewFunctionHelper(Handle<String> name,
606 Handle<Object> prototype) {
607 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name);
608 CALL_HEAP_FUNCTION(Heap::AllocateFunction(*Top::function_map(),
609 *function_share,
610 *prototype),
611 JSFunction);
612}
613
614
615Handle<JSFunction> Factory::NewFunction(Handle<String> name,
616 Handle<Object> prototype) {
617 Handle<JSFunction> fun = NewFunctionHelper(name, prototype);
618 fun->set_context(Top::context()->global_context());
619 return fun;
620}
621
622
623Handle<Object> Factory::ToObject(Handle<Object> object,
624 Handle<Context> global_context) {
625 CALL_HEAP_FUNCTION(object->ToObject(*global_context), Object);
626}
627
628
v8.team.kasperl727e9952008-09-02 14:56:44 +0000629Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
630 // Get the original code of the function.
631 Handle<Code> code(shared->code());
632
633 // Create a copy of the code before allocating the debug info object to avoid
634 // allocation while setting up the debug info object.
635 Handle<Code> original_code(*Factory::CopyCode(code));
636
637 // Allocate initial fixed array for active break points before allocating the
638 // debug info object to avoid allocation while setting up the debug info
639 // object.
640 Handle<FixedArray> break_points(
641 Factory::NewFixedArray(Debug::kEstimatedNofBreakPointsInFunction));
642
643 // Create and set up the debug info object. Debug info contains function, a
644 // copy of the original code, the executing code and initial fixed array for
645 // active break points.
646 Handle<DebugInfo> debug_info =
647 Handle<DebugInfo>::cast(Factory::NewStruct(DEBUG_INFO_TYPE));
648 debug_info->set_shared(*shared);
649 debug_info->set_original_code(*original_code);
650 debug_info->set_code(*code);
651 debug_info->set_break_points(*break_points);
652
653 // Link debug info to function.
654 shared->set_debug_info(*debug_info);
655
656 return debug_info;
657}
658
659
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000660Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee,
661 int length) {
662 CALL_HEAP_FUNCTION(Heap::AllocateArgumentsObject(*callee, length), JSObject);
663}
664
665
666Handle<JSFunction> Factory::CreateApiFunction(
667 Handle<FunctionTemplateInfo> obj,
668 bool is_global) {
669 Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::HandleApiCall));
670
kasper.lund212ac232008-07-16 07:07:30 +0000671 int internal_field_count = 0;
672 if (!obj->instance_template()->IsUndefined()) {
673 Handle<ObjectTemplateInfo> instance_template =
674 Handle<ObjectTemplateInfo>(
675 ObjectTemplateInfo::cast(obj->instance_template()));
676 internal_field_count =
677 Smi::cast(instance_template->internal_field_count())->value();
678 }
679
680 int instance_size = kPointerSize * internal_field_count;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000681 if (is_global) {
kasper.lund212ac232008-07-16 07:07:30 +0000682 instance_size += JSGlobalObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000683 } else {
kasper.lund212ac232008-07-16 07:07:30 +0000684 instance_size += JSObject::kHeaderSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000685 }
686
687 InstanceType type = is_global ? JS_GLOBAL_OBJECT_TYPE : JS_OBJECT_TYPE;
688
689 Handle<JSFunction> result =
kasper.lund212ac232008-07-16 07:07:30 +0000690 Factory::NewFunction(Factory::empty_symbol(), type, instance_size,
691 code, true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000692 // Set class name.
693 Handle<Object> class_name = Handle<Object>(obj->class_name());
694 if (class_name->IsString()) {
695 result->shared()->set_instance_class_name(*class_name);
696 result->shared()->set_name(*class_name);
697 }
698
699 Handle<Map> map = Handle<Map>(result->initial_map());
700
701 // Mark as undetectable if needed.
702 if (obj->undetectable()) {
703 map->set_is_undetectable();
704 }
705
706 // Mark as hidden for the __proto__ accessor if needed.
707 if (obj->hidden_prototype()) {
708 map->set_is_hidden_prototype();
709 }
710
711 // Mark as needs_access_check if needed.
712 if (obj->needs_access_check()) {
713 map->set_needs_access_check();
714 }
715
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716 // Set interceptor information in the map.
717 if (!obj->named_property_handler()->IsUndefined()) {
718 map->set_has_named_interceptor();
719 }
720 if (!obj->indexed_property_handler()->IsUndefined()) {
721 map->set_has_indexed_interceptor();
722 }
723
724 // Set instance call-as-function information in the map.
725 if (!obj->instance_call_handler()->IsUndefined()) {
726 map->set_has_instance_call_handler();
727 }
728
729 result->shared()->set_function_data(*obj);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000730 result->shared()->DontAdaptArguments();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000731
732 // Recursively copy parent templates' accessors, 'data' may be modified.
733 Handle<DescriptorArray> array =
734 Handle<DescriptorArray>(map->instance_descriptors());
735 while (true) {
736 Handle<Object> props = Handle<Object>(obj->property_accessors());
737 if (!props->IsUndefined()) {
738 array = Factory::CopyAppendCallbackDescriptors(array, props);
739 }
740 Handle<Object> parent = Handle<Object>(obj->parent_template());
741 if (parent->IsUndefined()) break;
742 obj = Handle<FunctionTemplateInfo>::cast(parent);
743 }
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000744 if (!array->IsEmpty()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745 map->set_instance_descriptors(*array);
746 }
747
748 return result;
749}
750
751
752void Factory::ConfigureInstance(Handle<FunctionTemplateInfo> desc,
753 Handle<JSObject> instance,
754 bool* pending_exception) {
755 // Configure the instance by adding the properties specified by the
756 // instance template.
757 Handle<Object> instance_template = Handle<Object>(desc->instance_template());
758 if (!instance_template->IsUndefined()) {
759 Execution::ConfigureInstance(instance,
760 instance_template,
761 pending_exception);
762 } else {
763 *pending_exception = false;
764 }
765}
766
767
768} } // namespace v8::internal