factory.cc revision 589d6979ff2ef66fca2d8fa51404c369ca5e9250
1// Copyright 2011 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#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#include "objects.h" 36#include "objects-visiting.h" 37#include "scopeinfo.h" 38 39namespace v8 { 40namespace internal { 41 42 43Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) { 44 ASSERT(0 <= size); 45 CALL_HEAP_FUNCTION( 46 isolate(), 47 isolate()->heap()->AllocateFixedArray(size, pretenure), 48 FixedArray); 49} 50 51 52Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size, 53 PretenureFlag pretenure) { 54 ASSERT(0 <= size); 55 CALL_HEAP_FUNCTION( 56 isolate(), 57 isolate()->heap()->AllocateFixedArrayWithHoles(size, pretenure), 58 FixedArray); 59} 60 61 62Handle<FixedArray> Factory::NewFixedDoubleArray(int size, 63 PretenureFlag pretenure) { 64 ASSERT(0 <= size); 65 CALL_HEAP_FUNCTION( 66 isolate(), 67 isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure), 68 FixedArray); 69} 70 71 72Handle<StringDictionary> Factory::NewStringDictionary(int at_least_space_for) { 73 ASSERT(0 <= at_least_space_for); 74 CALL_HEAP_FUNCTION(isolate(), 75 StringDictionary::Allocate(at_least_space_for), 76 StringDictionary); 77} 78 79 80Handle<NumberDictionary> Factory::NewNumberDictionary(int at_least_space_for) { 81 ASSERT(0 <= at_least_space_for); 82 CALL_HEAP_FUNCTION(isolate(), 83 NumberDictionary::Allocate(at_least_space_for), 84 NumberDictionary); 85} 86 87 88Handle<ObjectHashTable> Factory::NewObjectHashTable(int at_least_space_for) { 89 ASSERT(0 <= at_least_space_for); 90 CALL_HEAP_FUNCTION(isolate(), 91 ObjectHashTable::Allocate(at_least_space_for), 92 ObjectHashTable); 93} 94 95 96Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors) { 97 ASSERT(0 <= number_of_descriptors); 98 CALL_HEAP_FUNCTION(isolate(), 99 DescriptorArray::Allocate(number_of_descriptors), 100 DescriptorArray); 101} 102 103 104Handle<DeoptimizationInputData> Factory::NewDeoptimizationInputData( 105 int deopt_entry_count, 106 PretenureFlag pretenure) { 107 ASSERT(deopt_entry_count > 0); 108 CALL_HEAP_FUNCTION(isolate(), 109 DeoptimizationInputData::Allocate(deopt_entry_count, 110 pretenure), 111 DeoptimizationInputData); 112} 113 114 115Handle<DeoptimizationOutputData> Factory::NewDeoptimizationOutputData( 116 int deopt_entry_count, 117 PretenureFlag pretenure) { 118 ASSERT(deopt_entry_count > 0); 119 CALL_HEAP_FUNCTION(isolate(), 120 DeoptimizationOutputData::Allocate(deopt_entry_count, 121 pretenure), 122 DeoptimizationOutputData); 123} 124 125 126// Symbols are created in the old generation (data space). 127Handle<String> Factory::LookupSymbol(Vector<const char> string) { 128 CALL_HEAP_FUNCTION(isolate(), 129 isolate()->heap()->LookupSymbol(string), 130 String); 131} 132 133// Symbols are created in the old generation (data space). 134Handle<String> Factory::LookupSymbol(Handle<String> string) { 135 CALL_HEAP_FUNCTION(isolate(), 136 isolate()->heap()->LookupSymbol(*string), 137 String); 138} 139 140Handle<String> Factory::LookupAsciiSymbol(Vector<const char> string) { 141 CALL_HEAP_FUNCTION(isolate(), 142 isolate()->heap()->LookupAsciiSymbol(string), 143 String); 144} 145 146 147Handle<String> Factory::LookupAsciiSymbol(Handle<SeqAsciiString> string, 148 int from, 149 int length) { 150 CALL_HEAP_FUNCTION(isolate(), 151 isolate()->heap()->LookupAsciiSymbol(string, 152 from, 153 length), 154 String); 155} 156 157 158Handle<String> Factory::LookupTwoByteSymbol(Vector<const uc16> string) { 159 CALL_HEAP_FUNCTION(isolate(), 160 isolate()->heap()->LookupTwoByteSymbol(string), 161 String); 162} 163 164 165Handle<String> Factory::NewStringFromAscii(Vector<const char> string, 166 PretenureFlag pretenure) { 167 CALL_HEAP_FUNCTION( 168 isolate(), 169 isolate()->heap()->AllocateStringFromAscii(string, pretenure), 170 String); 171} 172 173Handle<String> Factory::NewStringFromUtf8(Vector<const char> string, 174 PretenureFlag pretenure) { 175 CALL_HEAP_FUNCTION( 176 isolate(), 177 isolate()->heap()->AllocateStringFromUtf8(string, pretenure), 178 String); 179} 180 181 182Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, 183 PretenureFlag pretenure) { 184 CALL_HEAP_FUNCTION( 185 isolate(), 186 isolate()->heap()->AllocateStringFromTwoByte(string, pretenure), 187 String); 188} 189 190 191Handle<SeqAsciiString> Factory::NewRawAsciiString(int length, 192 PretenureFlag pretenure) { 193 CALL_HEAP_FUNCTION( 194 isolate(), 195 isolate()->heap()->AllocateRawAsciiString(length, pretenure), 196 SeqAsciiString); 197} 198 199 200Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length, 201 PretenureFlag pretenure) { 202 CALL_HEAP_FUNCTION( 203 isolate(), 204 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), 205 SeqTwoByteString); 206} 207 208 209Handle<String> Factory::NewConsString(Handle<String> first, 210 Handle<String> second) { 211 CALL_HEAP_FUNCTION(isolate(), 212 isolate()->heap()->AllocateConsString(*first, *second), 213 String); 214} 215 216 217Handle<String> Factory::NewSubString(Handle<String> str, 218 int begin, 219 int end) { 220 CALL_HEAP_FUNCTION(isolate(), 221 str->SubString(begin, end), 222 String); 223} 224 225 226Handle<String> Factory::NewProperSubString(Handle<String> str, 227 int begin, 228 int end) { 229 ASSERT(begin > 0 || end < str->length()); 230 CALL_HEAP_FUNCTION(isolate(), 231 isolate()->heap()->AllocateSubString(*str, begin, end), 232 String); 233} 234 235 236Handle<String> Factory::NewExternalStringFromAscii( 237 ExternalAsciiString::Resource* resource) { 238 CALL_HEAP_FUNCTION( 239 isolate(), 240 isolate()->heap()->AllocateExternalStringFromAscii(resource), 241 String); 242} 243 244 245Handle<String> Factory::NewExternalStringFromTwoByte( 246 ExternalTwoByteString::Resource* resource) { 247 CALL_HEAP_FUNCTION( 248 isolate(), 249 isolate()->heap()->AllocateExternalStringFromTwoByte(resource), 250 String); 251} 252 253 254Handle<Context> Factory::NewGlobalContext() { 255 CALL_HEAP_FUNCTION( 256 isolate(), 257 isolate()->heap()->AllocateGlobalContext(), 258 Context); 259} 260 261 262Handle<Context> Factory::NewFunctionContext(int length, 263 Handle<JSFunction> function) { 264 CALL_HEAP_FUNCTION( 265 isolate(), 266 isolate()->heap()->AllocateFunctionContext(length, *function), 267 Context); 268} 269 270 271Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function, 272 Handle<Context> previous, 273 Handle<String> name, 274 Handle<Object> thrown_object) { 275 CALL_HEAP_FUNCTION( 276 isolate(), 277 isolate()->heap()->AllocateCatchContext(*function, 278 *previous, 279 *name, 280 *thrown_object), 281 Context); 282} 283 284 285Handle<Context> Factory::NewWithContext(Handle<JSFunction> function, 286 Handle<Context> previous, 287 Handle<JSObject> extension) { 288 CALL_HEAP_FUNCTION( 289 isolate(), 290 isolate()->heap()->AllocateWithContext(*function, *previous, *extension), 291 Context); 292} 293 294 295Handle<Context> Factory::NewBlockContext( 296 Handle<JSFunction> function, 297 Handle<Context> previous, 298 Handle<SerializedScopeInfo> scope_info) { 299 CALL_HEAP_FUNCTION( 300 isolate(), 301 isolate()->heap()->AllocateBlockContext(*function, 302 *previous, 303 *scope_info), 304 Context); 305} 306 307 308Handle<Struct> Factory::NewStruct(InstanceType type) { 309 CALL_HEAP_FUNCTION( 310 isolate(), 311 isolate()->heap()->AllocateStruct(type), 312 Struct); 313} 314 315 316Handle<AccessorInfo> Factory::NewAccessorInfo() { 317 Handle<AccessorInfo> info = 318 Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE)); 319 info->set_flag(0); // Must clear the flag, it was initialized as undefined. 320 return info; 321} 322 323 324Handle<Script> Factory::NewScript(Handle<String> source) { 325 // Generate id for this script. 326 int id; 327 Heap* heap = isolate()->heap(); 328 if (heap->last_script_id()->IsUndefined()) { 329 // Script ids start from one. 330 id = 1; 331 } else { 332 // Increment id, wrap when positive smi is exhausted. 333 id = Smi::cast(heap->last_script_id())->value(); 334 id++; 335 if (!Smi::IsValid(id)) { 336 id = 0; 337 } 338 } 339 heap->SetLastScriptId(Smi::FromInt(id)); 340 341 // Create and initialize script object. 342 Handle<Foreign> wrapper = NewForeign(0, TENURED); 343 Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE)); 344 script->set_source(*source); 345 script->set_name(heap->undefined_value()); 346 script->set_id(heap->last_script_id()); 347 script->set_line_offset(Smi::FromInt(0)); 348 script->set_column_offset(Smi::FromInt(0)); 349 script->set_data(heap->undefined_value()); 350 script->set_context_data(heap->undefined_value()); 351 script->set_type(Smi::FromInt(Script::TYPE_NORMAL)); 352 script->set_compilation_type(Smi::FromInt(Script::COMPILATION_TYPE_HOST)); 353 script->set_wrapper(*wrapper); 354 script->set_line_ends(heap->undefined_value()); 355 script->set_eval_from_shared(heap->undefined_value()); 356 script->set_eval_from_instructions_offset(Smi::FromInt(0)); 357 358 return script; 359} 360 361 362Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) { 363 CALL_HEAP_FUNCTION(isolate(), 364 isolate()->heap()->AllocateForeign(addr, pretenure), 365 Foreign); 366} 367 368 369Handle<Foreign> Factory::NewForeign(const AccessorDescriptor* desc) { 370 return NewForeign((Address) desc, TENURED); 371} 372 373 374Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) { 375 ASSERT(0 <= length); 376 CALL_HEAP_FUNCTION( 377 isolate(), 378 isolate()->heap()->AllocateByteArray(length, pretenure), 379 ByteArray); 380} 381 382 383Handle<ExternalArray> Factory::NewExternalArray(int length, 384 ExternalArrayType array_type, 385 void* external_pointer, 386 PretenureFlag pretenure) { 387 ASSERT(0 <= length); 388 CALL_HEAP_FUNCTION( 389 isolate(), 390 isolate()->heap()->AllocateExternalArray(length, 391 array_type, 392 external_pointer, 393 pretenure), 394 ExternalArray); 395} 396 397 398Handle<JSGlobalPropertyCell> Factory::NewJSGlobalPropertyCell( 399 Handle<Object> value) { 400 CALL_HEAP_FUNCTION( 401 isolate(), 402 isolate()->heap()->AllocateJSGlobalPropertyCell(*value), 403 JSGlobalPropertyCell); 404} 405 406 407Handle<Map> Factory::NewMap(InstanceType type, int instance_size) { 408 CALL_HEAP_FUNCTION( 409 isolate(), 410 isolate()->heap()->AllocateMap(type, instance_size), 411 Map); 412} 413 414 415Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) { 416 CALL_HEAP_FUNCTION( 417 isolate(), 418 isolate()->heap()->AllocateFunctionPrototype(*function), 419 JSObject); 420} 421 422 423Handle<Map> Factory::CopyMapDropDescriptors(Handle<Map> src) { 424 CALL_HEAP_FUNCTION(isolate(), src->CopyDropDescriptors(), Map); 425} 426 427 428Handle<Map> Factory::CopyMap(Handle<Map> src, 429 int extra_inobject_properties) { 430 Handle<Map> copy = CopyMapDropDescriptors(src); 431 // Check that we do not overflow the instance size when adding the 432 // extra inobject properties. 433 int instance_size_delta = extra_inobject_properties * kPointerSize; 434 int max_instance_size_delta = 435 JSObject::kMaxInstanceSize - copy->instance_size(); 436 if (instance_size_delta > max_instance_size_delta) { 437 // If the instance size overflows, we allocate as many properties 438 // as we can as inobject properties. 439 instance_size_delta = max_instance_size_delta; 440 extra_inobject_properties = max_instance_size_delta >> kPointerSizeLog2; 441 } 442 // Adjust the map with the extra inobject properties. 443 int inobject_properties = 444 copy->inobject_properties() + extra_inobject_properties; 445 copy->set_inobject_properties(inobject_properties); 446 copy->set_unused_property_fields(inobject_properties); 447 copy->set_instance_size(copy->instance_size() + instance_size_delta); 448 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); 449 return copy; 450} 451 452 453Handle<Map> Factory::CopyMapDropTransitions(Handle<Map> src) { 454 CALL_HEAP_FUNCTION(isolate(), src->CopyDropTransitions(), Map); 455} 456 457 458Handle<Map> Factory::GetFastElementsMap(Handle<Map> src) { 459 CALL_HEAP_FUNCTION(isolate(), src->GetFastElementsMap(), Map); 460} 461 462 463Handle<Map> Factory::GetSlowElementsMap(Handle<Map> src) { 464 CALL_HEAP_FUNCTION(isolate(), src->GetSlowElementsMap(), Map); 465} 466 467 468Handle<Map> Factory::GetElementsTransitionMap( 469 Handle<Map> src, 470 ElementsKind elements_kind, 471 bool safe_to_add_transition) { 472 CALL_HEAP_FUNCTION(isolate(), 473 src->GetElementsTransitionMap(elements_kind, 474 safe_to_add_transition), 475 Map); 476} 477 478 479Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) { 480 CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedArray); 481} 482 483 484Handle<JSFunction> Factory::BaseNewFunctionFromSharedFunctionInfo( 485 Handle<SharedFunctionInfo> function_info, 486 Handle<Map> function_map, 487 PretenureFlag pretenure) { 488 CALL_HEAP_FUNCTION( 489 isolate(), 490 isolate()->heap()->AllocateFunction(*function_map, 491 *function_info, 492 isolate()->heap()->the_hole_value(), 493 pretenure), 494 JSFunction); 495} 496 497 498Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( 499 Handle<SharedFunctionInfo> function_info, 500 Handle<Context> context, 501 PretenureFlag pretenure) { 502 Handle<JSFunction> result = BaseNewFunctionFromSharedFunctionInfo( 503 function_info, 504 function_info->strict_mode() 505 ? isolate()->strict_mode_function_map() 506 : isolate()->function_map(), 507 pretenure); 508 509 result->set_context(*context); 510 int number_of_literals = function_info->num_literals(); 511 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure); 512 if (number_of_literals > 0) { 513 // Store the object, regexp and array functions in the literals 514 // array prefix. These functions will be used when creating 515 // object, regexp and array literals in this function. 516 literals->set(JSFunction::kLiteralGlobalContextIndex, 517 context->global_context()); 518 } 519 result->set_literals(*literals); 520 result->set_next_function_link(isolate()->heap()->undefined_value()); 521 522 if (V8::UseCrankshaft() && 523 FLAG_always_opt && 524 result->is_compiled() && 525 !function_info->is_toplevel() && 526 function_info->allows_lazy_compilation()) { 527 result->MarkForLazyRecompilation(); 528 } 529 return result; 530} 531 532 533Handle<Object> Factory::NewNumber(double value, 534 PretenureFlag pretenure) { 535 CALL_HEAP_FUNCTION( 536 isolate(), 537 isolate()->heap()->NumberFromDouble(value, pretenure), Object); 538} 539 540 541Handle<Object> Factory::NewNumberFromInt(int value) { 542 CALL_HEAP_FUNCTION( 543 isolate(), 544 isolate()->heap()->NumberFromInt32(value), Object); 545} 546 547 548Handle<Object> Factory::NewNumberFromUint(uint32_t value) { 549 CALL_HEAP_FUNCTION( 550 isolate(), 551 isolate()->heap()->NumberFromUint32(value), Object); 552} 553 554 555Handle<JSObject> Factory::NewNeanderObject() { 556 CALL_HEAP_FUNCTION( 557 isolate(), 558 isolate()->heap()->AllocateJSObjectFromMap( 559 isolate()->heap()->neander_map()), 560 JSObject); 561} 562 563 564Handle<Object> Factory::NewTypeError(const char* type, 565 Vector< Handle<Object> > args) { 566 return NewError("MakeTypeError", type, args); 567} 568 569 570Handle<Object> Factory::NewTypeError(Handle<String> message) { 571 return NewError("$TypeError", message); 572} 573 574 575Handle<Object> Factory::NewRangeError(const char* type, 576 Vector< Handle<Object> > args) { 577 return NewError("MakeRangeError", type, args); 578} 579 580 581Handle<Object> Factory::NewRangeError(Handle<String> message) { 582 return NewError("$RangeError", message); 583} 584 585 586Handle<Object> Factory::NewSyntaxError(const char* type, Handle<JSArray> args) { 587 return NewError("MakeSyntaxError", type, args); 588} 589 590 591Handle<Object> Factory::NewSyntaxError(Handle<String> message) { 592 return NewError("$SyntaxError", message); 593} 594 595 596Handle<Object> Factory::NewReferenceError(const char* type, 597 Vector< Handle<Object> > args) { 598 return NewError("MakeReferenceError", type, args); 599} 600 601 602Handle<Object> Factory::NewReferenceError(Handle<String> message) { 603 return NewError("$ReferenceError", message); 604} 605 606 607Handle<Object> Factory::NewError(const char* maker, const char* type, 608 Vector< Handle<Object> > args) { 609 v8::HandleScope scope; // Instantiate a closeable HandleScope for EscapeFrom. 610 Handle<FixedArray> array = NewFixedArray(args.length()); 611 for (int i = 0; i < args.length(); i++) { 612 array->set(i, *args[i]); 613 } 614 Handle<JSArray> object = NewJSArrayWithElements(array); 615 Handle<Object> result = NewError(maker, type, object); 616 return result.EscapeFrom(&scope); 617} 618 619 620Handle<Object> Factory::NewEvalError(const char* type, 621 Vector< Handle<Object> > args) { 622 return NewError("MakeEvalError", type, args); 623} 624 625 626Handle<Object> Factory::NewError(const char* type, 627 Vector< Handle<Object> > args) { 628 return NewError("MakeError", type, args); 629} 630 631 632Handle<Object> Factory::NewError(const char* maker, 633 const char* type, 634 Handle<JSArray> args) { 635 Handle<String> make_str = LookupAsciiSymbol(maker); 636 Handle<Object> fun_obj( 637 isolate()->js_builtins_object()->GetPropertyNoExceptionThrown(*make_str)); 638 // If the builtins haven't been properly configured yet this error 639 // constructor may not have been defined. Bail out. 640 if (!fun_obj->IsJSFunction()) 641 return undefined_value(); 642 Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj); 643 Handle<Object> type_obj = LookupAsciiSymbol(type); 644 Object** argv[2] = { type_obj.location(), 645 Handle<Object>::cast(args).location() }; 646 647 // Invoke the JavaScript factory method. If an exception is thrown while 648 // running the factory method, use the exception as the result. 649 bool caught_exception; 650 Handle<Object> result = Execution::TryCall(fun, 651 isolate()->js_builtins_object(), 2, argv, &caught_exception); 652 return result; 653} 654 655 656Handle<Object> Factory::NewError(Handle<String> message) { 657 return NewError("$Error", message); 658} 659 660 661Handle<Object> Factory::NewError(const char* constructor, 662 Handle<String> message) { 663 Handle<String> constr = LookupAsciiSymbol(constructor); 664 Handle<JSFunction> fun = Handle<JSFunction>( 665 JSFunction::cast(isolate()->js_builtins_object()-> 666 GetPropertyNoExceptionThrown(*constr))); 667 Object** argv[1] = { Handle<Object>::cast(message).location() }; 668 669 // Invoke the JavaScript factory method. If an exception is thrown while 670 // running the factory method, use the exception as the result. 671 bool caught_exception; 672 Handle<Object> result = Execution::TryCall(fun, 673 isolate()->js_builtins_object(), 1, argv, &caught_exception); 674 return result; 675} 676 677 678Handle<JSFunction> Factory::NewFunction(Handle<String> name, 679 InstanceType type, 680 int instance_size, 681 Handle<Code> code, 682 bool force_initial_map) { 683 // Allocate the function 684 Handle<JSFunction> function = NewFunction(name, the_hole_value()); 685 686 // Setup the code pointer in both the shared function info and in 687 // the function itself. 688 function->shared()->set_code(*code); 689 function->set_code(*code); 690 691 if (force_initial_map || 692 type != JS_OBJECT_TYPE || 693 instance_size != JSObject::kHeaderSize) { 694 Handle<Map> initial_map = NewMap(type, instance_size); 695 Handle<JSObject> prototype = NewFunctionPrototype(function); 696 initial_map->set_prototype(*prototype); 697 function->set_initial_map(*initial_map); 698 initial_map->set_constructor(*function); 699 } else { 700 ASSERT(!function->has_initial_map()); 701 ASSERT(!function->has_prototype()); 702 } 703 704 return function; 705} 706 707 708Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name, 709 InstanceType type, 710 int instance_size, 711 Handle<JSObject> prototype, 712 Handle<Code> code, 713 bool force_initial_map) { 714 // Allocate the function. 715 Handle<JSFunction> function = NewFunction(name, prototype); 716 717 // Setup the code pointer in both the shared function info and in 718 // the function itself. 719 function->shared()->set_code(*code); 720 function->set_code(*code); 721 722 if (force_initial_map || 723 type != JS_OBJECT_TYPE || 724 instance_size != JSObject::kHeaderSize) { 725 Handle<Map> initial_map = NewMap(type, instance_size); 726 function->set_initial_map(*initial_map); 727 initial_map->set_constructor(*function); 728 } 729 730 // Set function.prototype and give the prototype a constructor 731 // property that refers to the function. 732 SetPrototypeProperty(function, prototype); 733 // Currently safe because it is only invoked from Genesis. 734 SetLocalPropertyNoThrow(prototype, constructor_symbol(), function, DONT_ENUM); 735 return function; 736} 737 738 739Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name, 740 Handle<Code> code) { 741 Handle<JSFunction> function = NewFunctionWithoutPrototype(name, 742 kNonStrictMode); 743 function->shared()->set_code(*code); 744 function->set_code(*code); 745 ASSERT(!function->has_initial_map()); 746 ASSERT(!function->has_prototype()); 747 return function; 748} 749 750 751Handle<SerializedScopeInfo> Factory::NewSerializedScopeInfo(int length) { 752 CALL_HEAP_FUNCTION( 753 isolate(), 754 isolate()->heap()->AllocateSerializedScopeInfo(length), 755 SerializedScopeInfo); 756} 757 758 759Handle<Code> Factory::NewCode(const CodeDesc& desc, 760 Code::Flags flags, 761 Handle<Object> self_ref, 762 bool immovable) { 763 CALL_HEAP_FUNCTION(isolate(), 764 isolate()->heap()->CreateCode( 765 desc, flags, self_ref, immovable), 766 Code); 767} 768 769 770Handle<Code> Factory::CopyCode(Handle<Code> code) { 771 CALL_HEAP_FUNCTION(isolate(), 772 isolate()->heap()->CopyCode(*code), 773 Code); 774} 775 776 777Handle<Code> Factory::CopyCode(Handle<Code> code, Vector<byte> reloc_info) { 778 CALL_HEAP_FUNCTION(isolate(), 779 isolate()->heap()->CopyCode(*code, reloc_info), 780 Code); 781} 782 783 784MUST_USE_RESULT static inline MaybeObject* DoCopyInsert( 785 DescriptorArray* array, 786 String* key, 787 Object* value, 788 PropertyAttributes attributes) { 789 CallbacksDescriptor desc(key, value, attributes); 790 MaybeObject* obj = array->CopyInsert(&desc, REMOVE_TRANSITIONS); 791 return obj; 792} 793 794 795// Allocate the new array. 796Handle<DescriptorArray> Factory::CopyAppendForeignDescriptor( 797 Handle<DescriptorArray> array, 798 Handle<String> key, 799 Handle<Object> value, 800 PropertyAttributes attributes) { 801 CALL_HEAP_FUNCTION(isolate(), 802 DoCopyInsert(*array, *key, *value, attributes), 803 DescriptorArray); 804} 805 806 807Handle<String> Factory::SymbolFromString(Handle<String> value) { 808 CALL_HEAP_FUNCTION(isolate(), 809 isolate()->heap()->LookupSymbol(*value), String); 810} 811 812 813Handle<DescriptorArray> Factory::CopyAppendCallbackDescriptors( 814 Handle<DescriptorArray> array, 815 Handle<Object> descriptors) { 816 v8::NeanderArray callbacks(descriptors); 817 int nof_callbacks = callbacks.length(); 818 Handle<DescriptorArray> result = 819 NewDescriptorArray(array->number_of_descriptors() + nof_callbacks); 820 821 // Number of descriptors added to the result so far. 822 int descriptor_count = 0; 823 824 // Copy the descriptors from the array. 825 for (int i = 0; i < array->number_of_descriptors(); i++) { 826 if (array->GetType(i) != NULL_DESCRIPTOR) { 827 result->CopyFrom(descriptor_count++, *array, i); 828 } 829 } 830 831 // Number of duplicates detected. 832 int duplicates = 0; 833 834 // Fill in new callback descriptors. Process the callbacks from 835 // back to front so that the last callback with a given name takes 836 // precedence over previously added callbacks with that name. 837 for (int i = nof_callbacks - 1; i >= 0; i--) { 838 Handle<AccessorInfo> entry = 839 Handle<AccessorInfo>(AccessorInfo::cast(callbacks.get(i))); 840 // Ensure the key is a symbol before writing into the instance descriptor. 841 Handle<String> key = 842 SymbolFromString(Handle<String>(String::cast(entry->name()))); 843 // Check if a descriptor with this name already exists before writing. 844 if (result->LinearSearch(*key, descriptor_count) == 845 DescriptorArray::kNotFound) { 846 CallbacksDescriptor desc(*key, *entry, entry->property_attributes()); 847 result->Set(descriptor_count, &desc); 848 descriptor_count++; 849 } else { 850 duplicates++; 851 } 852 } 853 854 // If duplicates were detected, allocate a result of the right size 855 // and transfer the elements. 856 if (duplicates > 0) { 857 int number_of_descriptors = result->number_of_descriptors() - duplicates; 858 Handle<DescriptorArray> new_result = 859 NewDescriptorArray(number_of_descriptors); 860 for (int i = 0; i < number_of_descriptors; i++) { 861 new_result->CopyFrom(i, *result, i); 862 } 863 result = new_result; 864 } 865 866 // Sort the result before returning. 867 result->Sort(); 868 return result; 869} 870 871 872Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, 873 PretenureFlag pretenure) { 874 CALL_HEAP_FUNCTION( 875 isolate(), 876 isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); 877} 878 879 880Handle<GlobalObject> Factory::NewGlobalObject( 881 Handle<JSFunction> constructor) { 882 CALL_HEAP_FUNCTION(isolate(), 883 isolate()->heap()->AllocateGlobalObject(*constructor), 884 GlobalObject); 885} 886 887 888 889Handle<JSObject> Factory::NewJSObjectFromMap(Handle<Map> map) { 890 CALL_HEAP_FUNCTION( 891 isolate(), 892 isolate()->heap()->AllocateJSObjectFromMap(*map, NOT_TENURED), 893 JSObject); 894} 895 896 897Handle<JSArray> Factory::NewJSArray(int capacity, 898 PretenureFlag pretenure) { 899 Handle<JSObject> obj = NewJSObject(isolate()->array_function(), pretenure); 900 CALL_HEAP_FUNCTION(isolate(), 901 Handle<JSArray>::cast(obj)->Initialize(capacity), 902 JSArray); 903} 904 905 906Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArray> elements, 907 PretenureFlag pretenure) { 908 Handle<JSArray> result = 909 Handle<JSArray>::cast(NewJSObject(isolate()->array_function(), 910 pretenure)); 911 result->SetContent(*elements); 912 return result; 913} 914 915 916Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler, 917 Handle<Object> prototype) { 918 CALL_HEAP_FUNCTION( 919 isolate(), 920 isolate()->heap()->AllocateJSProxy(*handler, *prototype), 921 JSProxy); 922} 923 924 925void Factory::BecomeJSObject(Handle<JSReceiver> object) { 926 CALL_HEAP_FUNCTION_VOID( 927 isolate(), 928 isolate()->heap()->ReinitializeJSReceiver( 929 *object, JS_OBJECT_TYPE, JSObject::kHeaderSize)); 930} 931 932 933void Factory::BecomeJSFunction(Handle<JSReceiver> object) { 934 CALL_HEAP_FUNCTION_VOID( 935 isolate(), 936 isolate()->heap()->ReinitializeJSReceiver( 937 *object, JS_FUNCTION_TYPE, JSFunction::kSize)); 938} 939 940 941Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( 942 Handle<String> name, 943 int number_of_literals, 944 Handle<Code> code, 945 Handle<SerializedScopeInfo> scope_info) { 946 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name); 947 shared->set_code(*code); 948 shared->set_scope_info(*scope_info); 949 int literals_array_size = number_of_literals; 950 // If the function contains object, regexp or array literals, 951 // allocate extra space for a literals array prefix containing the 952 // context. 953 if (number_of_literals > 0) { 954 literals_array_size += JSFunction::kLiteralsPrefixSize; 955 } 956 shared->set_num_literals(literals_array_size); 957 return shared; 958} 959 960 961Handle<JSMessageObject> Factory::NewJSMessageObject( 962 Handle<String> type, 963 Handle<JSArray> arguments, 964 int start_position, 965 int end_position, 966 Handle<Object> script, 967 Handle<Object> stack_trace, 968 Handle<Object> stack_frames) { 969 CALL_HEAP_FUNCTION(isolate(), 970 isolate()->heap()->AllocateJSMessageObject(*type, 971 *arguments, 972 start_position, 973 end_position, 974 *script, 975 *stack_trace, 976 *stack_frames), 977 JSMessageObject); 978} 979 980Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) { 981 CALL_HEAP_FUNCTION(isolate(), 982 isolate()->heap()->AllocateSharedFunctionInfo(*name), 983 SharedFunctionInfo); 984} 985 986 987Handle<String> Factory::NumberToString(Handle<Object> number) { 988 CALL_HEAP_FUNCTION(isolate(), 989 isolate()->heap()->NumberToString(*number), String); 990} 991 992 993Handle<NumberDictionary> Factory::DictionaryAtNumberPut( 994 Handle<NumberDictionary> dictionary, 995 uint32_t key, 996 Handle<Object> value) { 997 CALL_HEAP_FUNCTION(isolate(), 998 dictionary->AtNumberPut(key, *value), 999 NumberDictionary); 1000} 1001 1002 1003Handle<JSFunction> Factory::NewFunctionHelper(Handle<String> name, 1004 Handle<Object> prototype) { 1005 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name); 1006 CALL_HEAP_FUNCTION( 1007 isolate(), 1008 isolate()->heap()->AllocateFunction(*isolate()->function_map(), 1009 *function_share, 1010 *prototype), 1011 JSFunction); 1012} 1013 1014 1015Handle<JSFunction> Factory::NewFunction(Handle<String> name, 1016 Handle<Object> prototype) { 1017 Handle<JSFunction> fun = NewFunctionHelper(name, prototype); 1018 fun->set_context(isolate()->context()->global_context()); 1019 return fun; 1020} 1021 1022 1023Handle<JSFunction> Factory::NewFunctionWithoutPrototypeHelper( 1024 Handle<String> name, 1025 StrictModeFlag strict_mode) { 1026 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name); 1027 Handle<Map> map = strict_mode == kStrictMode 1028 ? isolate()->strict_mode_function_without_prototype_map() 1029 : isolate()->function_without_prototype_map(); 1030 CALL_HEAP_FUNCTION(isolate(), 1031 isolate()->heap()->AllocateFunction( 1032 *map, 1033 *function_share, 1034 *the_hole_value()), 1035 JSFunction); 1036} 1037 1038 1039Handle<JSFunction> Factory::NewFunctionWithoutPrototype( 1040 Handle<String> name, 1041 StrictModeFlag strict_mode) { 1042 Handle<JSFunction> fun = NewFunctionWithoutPrototypeHelper(name, strict_mode); 1043 fun->set_context(isolate()->context()->global_context()); 1044 return fun; 1045} 1046 1047 1048Handle<Object> Factory::ToObject(Handle<Object> object) { 1049 CALL_HEAP_FUNCTION(isolate(), object->ToObject(), Object); 1050} 1051 1052 1053Handle<Object> Factory::ToObject(Handle<Object> object, 1054 Handle<Context> global_context) { 1055 CALL_HEAP_FUNCTION(isolate(), object->ToObject(*global_context), Object); 1056} 1057 1058 1059#ifdef ENABLE_DEBUGGER_SUPPORT 1060Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { 1061 // Get the original code of the function. 1062 Handle<Code> code(shared->code()); 1063 1064 // Create a copy of the code before allocating the debug info object to avoid 1065 // allocation while setting up the debug info object. 1066 Handle<Code> original_code(*Factory::CopyCode(code)); 1067 1068 // Allocate initial fixed array for active break points before allocating the 1069 // debug info object to avoid allocation while setting up the debug info 1070 // object. 1071 Handle<FixedArray> break_points( 1072 NewFixedArray(Debug::kEstimatedNofBreakPointsInFunction)); 1073 1074 // Create and set up the debug info object. Debug info contains function, a 1075 // copy of the original code, the executing code and initial fixed array for 1076 // active break points. 1077 Handle<DebugInfo> debug_info = 1078 Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE)); 1079 debug_info->set_shared(*shared); 1080 debug_info->set_original_code(*original_code); 1081 debug_info->set_code(*code); 1082 debug_info->set_break_points(*break_points); 1083 1084 // Link debug info to function. 1085 shared->set_debug_info(*debug_info); 1086 1087 return debug_info; 1088} 1089#endif 1090 1091 1092Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee, 1093 int length) { 1094 CALL_HEAP_FUNCTION( 1095 isolate(), 1096 isolate()->heap()->AllocateArgumentsObject(*callee, length), JSObject); 1097} 1098 1099 1100Handle<JSFunction> Factory::CreateApiFunction( 1101 Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) { 1102 Handle<Code> code = isolate()->builtins()->HandleApiCall(); 1103 Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi(); 1104 1105 int internal_field_count = 0; 1106 if (!obj->instance_template()->IsUndefined()) { 1107 Handle<ObjectTemplateInfo> instance_template = 1108 Handle<ObjectTemplateInfo>( 1109 ObjectTemplateInfo::cast(obj->instance_template())); 1110 internal_field_count = 1111 Smi::cast(instance_template->internal_field_count())->value(); 1112 } 1113 1114 int instance_size = kPointerSize * internal_field_count; 1115 InstanceType type = INVALID_TYPE; 1116 switch (instance_type) { 1117 case JavaScriptObject: 1118 type = JS_OBJECT_TYPE; 1119 instance_size += JSObject::kHeaderSize; 1120 break; 1121 case InnerGlobalObject: 1122 type = JS_GLOBAL_OBJECT_TYPE; 1123 instance_size += JSGlobalObject::kSize; 1124 break; 1125 case OuterGlobalObject: 1126 type = JS_GLOBAL_PROXY_TYPE; 1127 instance_size += JSGlobalProxy::kSize; 1128 break; 1129 default: 1130 break; 1131 } 1132 ASSERT(type != INVALID_TYPE); 1133 1134 Handle<JSFunction> result = 1135 NewFunction(Factory::empty_symbol(), 1136 type, 1137 instance_size, 1138 code, 1139 true); 1140 // Set class name. 1141 Handle<Object> class_name = Handle<Object>(obj->class_name()); 1142 if (class_name->IsString()) { 1143 result->shared()->set_instance_class_name(*class_name); 1144 result->shared()->set_name(*class_name); 1145 } 1146 1147 Handle<Map> map = Handle<Map>(result->initial_map()); 1148 1149 // Mark as undetectable if needed. 1150 if (obj->undetectable()) { 1151 map->set_is_undetectable(); 1152 } 1153 1154 // Mark as hidden for the __proto__ accessor if needed. 1155 if (obj->hidden_prototype()) { 1156 map->set_is_hidden_prototype(); 1157 } 1158 1159 // Mark as needs_access_check if needed. 1160 if (obj->needs_access_check()) { 1161 map->set_is_access_check_needed(true); 1162 } 1163 1164 // Set interceptor information in the map. 1165 if (!obj->named_property_handler()->IsUndefined()) { 1166 map->set_has_named_interceptor(); 1167 } 1168 if (!obj->indexed_property_handler()->IsUndefined()) { 1169 map->set_has_indexed_interceptor(); 1170 } 1171 1172 // Set instance call-as-function information in the map. 1173 if (!obj->instance_call_handler()->IsUndefined()) { 1174 map->set_has_instance_call_handler(); 1175 } 1176 1177 result->shared()->set_function_data(*obj); 1178 result->shared()->set_construct_stub(*construct_stub); 1179 result->shared()->DontAdaptArguments(); 1180 1181 // Recursively copy parent templates' accessors, 'data' may be modified. 1182 Handle<DescriptorArray> array = 1183 Handle<DescriptorArray>(map->instance_descriptors()); 1184 while (true) { 1185 Handle<Object> props = Handle<Object>(obj->property_accessors()); 1186 if (!props->IsUndefined()) { 1187 array = CopyAppendCallbackDescriptors(array, props); 1188 } 1189 Handle<Object> parent = Handle<Object>(obj->parent_template()); 1190 if (parent->IsUndefined()) break; 1191 obj = Handle<FunctionTemplateInfo>::cast(parent); 1192 } 1193 if (!array->IsEmpty()) { 1194 map->set_instance_descriptors(*array); 1195 } 1196 1197 ASSERT(result->shared()->IsApiFunction()); 1198 return result; 1199} 1200 1201 1202Handle<MapCache> Factory::NewMapCache(int at_least_space_for) { 1203 CALL_HEAP_FUNCTION(isolate(), 1204 MapCache::Allocate(at_least_space_for), MapCache); 1205} 1206 1207 1208MUST_USE_RESULT static MaybeObject* UpdateMapCacheWith(Context* context, 1209 FixedArray* keys, 1210 Map* map) { 1211 Object* result; 1212 { MaybeObject* maybe_result = 1213 MapCache::cast(context->map_cache())->Put(keys, map); 1214 if (!maybe_result->ToObject(&result)) return maybe_result; 1215 } 1216 context->set_map_cache(MapCache::cast(result)); 1217 return result; 1218} 1219 1220 1221Handle<MapCache> Factory::AddToMapCache(Handle<Context> context, 1222 Handle<FixedArray> keys, 1223 Handle<Map> map) { 1224 CALL_HEAP_FUNCTION(isolate(), 1225 UpdateMapCacheWith(*context, *keys, *map), MapCache); 1226} 1227 1228 1229Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context, 1230 Handle<FixedArray> keys) { 1231 if (context->map_cache()->IsUndefined()) { 1232 // Allocate the new map cache for the global context. 1233 Handle<MapCache> new_cache = NewMapCache(24); 1234 context->set_map_cache(*new_cache); 1235 } 1236 // Check to see whether there is a matching element in the cache. 1237 Handle<MapCache> cache = 1238 Handle<MapCache>(MapCache::cast(context->map_cache())); 1239 Handle<Object> result = Handle<Object>(cache->Lookup(*keys)); 1240 if (result->IsMap()) return Handle<Map>::cast(result); 1241 // Create a new map and add it to the cache. 1242 Handle<Map> map = 1243 CopyMap(Handle<Map>(context->object_function()->initial_map()), 1244 keys->length()); 1245 AddToMapCache(context, keys, map); 1246 return Handle<Map>(map); 1247} 1248 1249 1250void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp, 1251 JSRegExp::Type type, 1252 Handle<String> source, 1253 JSRegExp::Flags flags, 1254 Handle<Object> data) { 1255 Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize); 1256 1257 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); 1258 store->set(JSRegExp::kSourceIndex, *source); 1259 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value())); 1260 store->set(JSRegExp::kAtomPatternIndex, *data); 1261 regexp->set_data(*store); 1262} 1263 1264void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, 1265 JSRegExp::Type type, 1266 Handle<String> source, 1267 JSRegExp::Flags flags, 1268 int capture_count) { 1269 Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize); 1270 Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue); 1271 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); 1272 store->set(JSRegExp::kSourceIndex, *source); 1273 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value())); 1274 store->set(JSRegExp::kIrregexpASCIICodeIndex, uninitialized); 1275 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); 1276 store->set(JSRegExp::kIrregexpASCIICodeSavedIndex, uninitialized); 1277 store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); 1278 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0)); 1279 store->set(JSRegExp::kIrregexpCaptureCountIndex, 1280 Smi::FromInt(capture_count)); 1281 regexp->set_data(*store); 1282} 1283 1284 1285 1286void Factory::ConfigureInstance(Handle<FunctionTemplateInfo> desc, 1287 Handle<JSObject> instance, 1288 bool* pending_exception) { 1289 // Configure the instance by adding the properties specified by the 1290 // instance template. 1291 Handle<Object> instance_template = Handle<Object>(desc->instance_template()); 1292 if (!instance_template->IsUndefined()) { 1293 Execution::ConfigureInstance(instance, 1294 instance_template, 1295 pending_exception); 1296 } else { 1297 *pending_exception = false; 1298 } 1299} 1300 1301 1302} } // namespace v8::internal 1303