1 // Copyright 2013 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 "isolate-inl.h" 35 #include "macro-assembler.h" 36 #include "objects.h" 37 #include "objects-visiting.h" 38 #include "platform.h" 39 #include "scopeinfo.h" 40 41 namespace v8 { 42 namespace internal { 43 44 45 Handle<Box> Factory::NewBox(Handle<Object> value, PretenureFlag pretenure) { 46 CALL_HEAP_FUNCTION( 47 isolate(), 48 isolate()->heap()->AllocateBox(*value, pretenure), 49 Box); 50 } 51 52 53 Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) { 54 ASSERT(0 <= size); 55 CALL_HEAP_FUNCTION( 56 isolate(), 57 isolate()->heap()->AllocateFixedArray(size, pretenure), 58 FixedArray); 59 } 60 61 62 Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size, 63 PretenureFlag pretenure) { 64 ASSERT(0 <= size); 65 CALL_HEAP_FUNCTION( 66 isolate(), 67 isolate()->heap()->AllocateFixedArrayWithHoles(size, pretenure), 68 FixedArray); 69 } 70 71 72 Handle<FixedDoubleArray> Factory::NewFixedDoubleArray(int size, 73 PretenureFlag pretenure) { 74 ASSERT(0 <= size); 75 CALL_HEAP_FUNCTION( 76 isolate(), 77 isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure), 78 FixedDoubleArray); 79 } 80 81 82 Handle<ConstantPoolArray> Factory::NewConstantPoolArray( 83 int number_of_int64_entries, 84 int number_of_ptr_entries, 85 int number_of_int32_entries) { 86 ASSERT(number_of_int64_entries > 0 || number_of_ptr_entries > 0 || 87 number_of_int32_entries > 0); 88 CALL_HEAP_FUNCTION( 89 isolate(), 90 isolate()->heap()->AllocateConstantPoolArray(number_of_int64_entries, 91 number_of_ptr_entries, 92 number_of_int32_entries), 93 ConstantPoolArray); 94 } 95 96 97 Handle<NameDictionary> Factory::NewNameDictionary(int at_least_space_for) { 98 ASSERT(0 <= at_least_space_for); 99 CALL_HEAP_FUNCTION(isolate(), 100 NameDictionary::Allocate(isolate()->heap(), 101 at_least_space_for), 102 NameDictionary); 103 } 104 105 106 Handle<SeededNumberDictionary> Factory::NewSeededNumberDictionary( 107 int at_least_space_for) { 108 ASSERT(0 <= at_least_space_for); 109 CALL_HEAP_FUNCTION(isolate(), 110 SeededNumberDictionary::Allocate(isolate()->heap(), 111 at_least_space_for), 112 SeededNumberDictionary); 113 } 114 115 116 Handle<UnseededNumberDictionary> Factory::NewUnseededNumberDictionary( 117 int at_least_space_for) { 118 ASSERT(0 <= at_least_space_for); 119 CALL_HEAP_FUNCTION(isolate(), 120 UnseededNumberDictionary::Allocate(isolate()->heap(), 121 at_least_space_for), 122 UnseededNumberDictionary); 123 } 124 125 126 Handle<ObjectHashSet> Factory::NewObjectHashSet(int at_least_space_for) { 127 ASSERT(0 <= at_least_space_for); 128 CALL_HEAP_FUNCTION(isolate(), 129 ObjectHashSet::Allocate(isolate()->heap(), 130 at_least_space_for), 131 ObjectHashSet); 132 } 133 134 135 Handle<ObjectHashTable> Factory::NewObjectHashTable( 136 int at_least_space_for, 137 MinimumCapacity capacity_option) { 138 ASSERT(0 <= at_least_space_for); 139 CALL_HEAP_FUNCTION(isolate(), 140 ObjectHashTable::Allocate(isolate()->heap(), 141 at_least_space_for, 142 capacity_option), 143 ObjectHashTable); 144 } 145 146 147 Handle<WeakHashTable> Factory::NewWeakHashTable(int at_least_space_for) { 148 ASSERT(0 <= at_least_space_for); 149 CALL_HEAP_FUNCTION( 150 isolate(), 151 WeakHashTable::Allocate(isolate()->heap(), 152 at_least_space_for, 153 USE_DEFAULT_MINIMUM_CAPACITY, 154 TENURED), 155 WeakHashTable); 156 } 157 158 159 Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors, 160 int slack) { 161 ASSERT(0 <= number_of_descriptors); 162 CALL_HEAP_FUNCTION(isolate(), 163 DescriptorArray::Allocate( 164 isolate(), number_of_descriptors, slack), 165 DescriptorArray); 166 } 167 168 169 Handle<DeoptimizationInputData> Factory::NewDeoptimizationInputData( 170 int deopt_entry_count, 171 PretenureFlag pretenure) { 172 ASSERT(deopt_entry_count > 0); 173 CALL_HEAP_FUNCTION(isolate(), 174 DeoptimizationInputData::Allocate(isolate(), 175 deopt_entry_count, 176 pretenure), 177 DeoptimizationInputData); 178 } 179 180 181 Handle<DeoptimizationOutputData> Factory::NewDeoptimizationOutputData( 182 int deopt_entry_count, 183 PretenureFlag pretenure) { 184 ASSERT(deopt_entry_count > 0); 185 CALL_HEAP_FUNCTION(isolate(), 186 DeoptimizationOutputData::Allocate(isolate(), 187 deopt_entry_count, 188 pretenure), 189 DeoptimizationOutputData); 190 } 191 192 193 Handle<AccessorPair> Factory::NewAccessorPair() { 194 CALL_HEAP_FUNCTION(isolate(), 195 isolate()->heap()->AllocateAccessorPair(), 196 AccessorPair); 197 } 198 199 200 Handle<TypeFeedbackInfo> Factory::NewTypeFeedbackInfo() { 201 CALL_HEAP_FUNCTION(isolate(), 202 isolate()->heap()->AllocateTypeFeedbackInfo(), 203 TypeFeedbackInfo); 204 } 205 206 207 // Internalized strings are created in the old generation (data space). 208 Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) { 209 CALL_HEAP_FUNCTION(isolate(), 210 isolate()->heap()->InternalizeUtf8String(string), 211 String); 212 } 213 214 215 // Internalized strings are created in the old generation (data space). 216 Handle<String> Factory::InternalizeString(Handle<String> string) { 217 CALL_HEAP_FUNCTION(isolate(), 218 isolate()->heap()->InternalizeString(*string), 219 String); 220 } 221 222 223 Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) { 224 CALL_HEAP_FUNCTION(isolate(), 225 isolate()->heap()->InternalizeOneByteString(string), 226 String); 227 } 228 229 230 Handle<String> Factory::InternalizeOneByteString( 231 Handle<SeqOneByteString> string, int from, int length) { 232 CALL_HEAP_FUNCTION(isolate(), 233 isolate()->heap()->InternalizeOneByteString( 234 string, from, length), 235 String); 236 } 237 238 239 Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) { 240 CALL_HEAP_FUNCTION(isolate(), 241 isolate()->heap()->InternalizeTwoByteString(string), 242 String); 243 } 244 245 246 Handle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, 247 PretenureFlag pretenure) { 248 CALL_HEAP_FUNCTION( 249 isolate(), 250 isolate()->heap()->AllocateStringFromOneByte(string, pretenure), 251 String); 252 } 253 254 Handle<String> Factory::NewStringFromUtf8(Vector<const char> string, 255 PretenureFlag pretenure) { 256 CALL_HEAP_FUNCTION( 257 isolate(), 258 isolate()->heap()->AllocateStringFromUtf8(string, pretenure), 259 String); 260 } 261 262 263 Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, 264 PretenureFlag pretenure) { 265 CALL_HEAP_FUNCTION( 266 isolate(), 267 isolate()->heap()->AllocateStringFromTwoByte(string, pretenure), 268 String); 269 } 270 271 272 Handle<SeqOneByteString> Factory::NewRawOneByteString(int length, 273 PretenureFlag pretenure) { 274 CALL_HEAP_FUNCTION( 275 isolate(), 276 isolate()->heap()->AllocateRawOneByteString(length, pretenure), 277 SeqOneByteString); 278 } 279 280 281 Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length, 282 PretenureFlag pretenure) { 283 CALL_HEAP_FUNCTION( 284 isolate(), 285 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), 286 SeqTwoByteString); 287 } 288 289 290 Handle<String> Factory::NewConsString(Handle<String> first, 291 Handle<String> second) { 292 CALL_HEAP_FUNCTION(isolate(), 293 isolate()->heap()->AllocateConsString(*first, *second), 294 String); 295 } 296 297 298 template<typename SinkChar, typename StringType> 299 Handle<String> ConcatStringContent(Handle<StringType> result, 300 Handle<String> first, 301 Handle<String> second) { 302 DisallowHeapAllocation pointer_stays_valid; 303 SinkChar* sink = result->GetChars(); 304 String::WriteToFlat(*first, sink, 0, first->length()); 305 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); 306 return result; 307 } 308 309 310 Handle<String> Factory::NewFlatConcatString(Handle<String> first, 311 Handle<String> second) { 312 int total_length = first->length() + second->length(); 313 if (first->IsOneByteRepresentation() && second->IsOneByteRepresentation()) { 314 return ConcatStringContent<uint8_t>( 315 NewRawOneByteString(total_length), first, second); 316 } else { 317 return ConcatStringContent<uc16>( 318 NewRawTwoByteString(total_length), first, second); 319 } 320 } 321 322 323 Handle<String> Factory::NewSubString(Handle<String> str, 324 int begin, 325 int end) { 326 CALL_HEAP_FUNCTION(isolate(), 327 str->SubString(begin, end), 328 String); 329 } 330 331 332 Handle<String> Factory::NewProperSubString(Handle<String> str, 333 int begin, 334 int end) { 335 ASSERT(begin > 0 || end < str->length()); 336 CALL_HEAP_FUNCTION(isolate(), 337 isolate()->heap()->AllocateSubString(*str, begin, end), 338 String); 339 } 340 341 342 Handle<String> Factory::NewExternalStringFromAscii( 343 const ExternalAsciiString::Resource* resource) { 344 CALL_HEAP_FUNCTION( 345 isolate(), 346 isolate()->heap()->AllocateExternalStringFromAscii(resource), 347 String); 348 } 349 350 351 Handle<String> Factory::NewExternalStringFromTwoByte( 352 const ExternalTwoByteString::Resource* resource) { 353 CALL_HEAP_FUNCTION( 354 isolate(), 355 isolate()->heap()->AllocateExternalStringFromTwoByte(resource), 356 String); 357 } 358 359 360 Handle<Symbol> Factory::NewSymbol() { 361 CALL_HEAP_FUNCTION( 362 isolate(), 363 isolate()->heap()->AllocateSymbol(), 364 Symbol); 365 } 366 367 368 Handle<Symbol> Factory::NewPrivateSymbol() { 369 CALL_HEAP_FUNCTION( 370 isolate(), 371 isolate()->heap()->AllocatePrivateSymbol(), 372 Symbol); 373 } 374 375 376 Handle<Context> Factory::NewNativeContext() { 377 CALL_HEAP_FUNCTION( 378 isolate(), 379 isolate()->heap()->AllocateNativeContext(), 380 Context); 381 } 382 383 384 Handle<Context> Factory::NewGlobalContext(Handle<JSFunction> function, 385 Handle<ScopeInfo> scope_info) { 386 CALL_HEAP_FUNCTION( 387 isolate(), 388 isolate()->heap()->AllocateGlobalContext(*function, *scope_info), 389 Context); 390 } 391 392 393 Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) { 394 CALL_HEAP_FUNCTION( 395 isolate(), 396 isolate()->heap()->AllocateModuleContext(*scope_info), 397 Context); 398 } 399 400 401 Handle<Context> Factory::NewFunctionContext(int length, 402 Handle<JSFunction> function) { 403 CALL_HEAP_FUNCTION( 404 isolate(), 405 isolate()->heap()->AllocateFunctionContext(length, *function), 406 Context); 407 } 408 409 410 Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function, 411 Handle<Context> previous, 412 Handle<String> name, 413 Handle<Object> thrown_object) { 414 CALL_HEAP_FUNCTION( 415 isolate(), 416 isolate()->heap()->AllocateCatchContext(*function, 417 *previous, 418 *name, 419 *thrown_object), 420 Context); 421 } 422 423 424 Handle<Context> Factory::NewWithContext(Handle<JSFunction> function, 425 Handle<Context> previous, 426 Handle<JSObject> extension) { 427 CALL_HEAP_FUNCTION( 428 isolate(), 429 isolate()->heap()->AllocateWithContext(*function, *previous, *extension), 430 Context); 431 } 432 433 434 Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function, 435 Handle<Context> previous, 436 Handle<ScopeInfo> scope_info) { 437 CALL_HEAP_FUNCTION( 438 isolate(), 439 isolate()->heap()->AllocateBlockContext(*function, 440 *previous, 441 *scope_info), 442 Context); 443 } 444 445 446 Handle<Struct> Factory::NewStruct(InstanceType type) { 447 CALL_HEAP_FUNCTION( 448 isolate(), 449 isolate()->heap()->AllocateStruct(type), 450 Struct); 451 } 452 453 454 Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry( 455 int aliased_context_slot) { 456 Handle<AliasedArgumentsEntry> entry = Handle<AliasedArgumentsEntry>::cast( 457 NewStruct(ALIASED_ARGUMENTS_ENTRY_TYPE)); 458 entry->set_aliased_context_slot(aliased_context_slot); 459 return entry; 460 } 461 462 463 Handle<DeclaredAccessorDescriptor> Factory::NewDeclaredAccessorDescriptor() { 464 return Handle<DeclaredAccessorDescriptor>::cast( 465 NewStruct(DECLARED_ACCESSOR_DESCRIPTOR_TYPE)); 466 } 467 468 469 Handle<DeclaredAccessorInfo> Factory::NewDeclaredAccessorInfo() { 470 Handle<DeclaredAccessorInfo> info = 471 Handle<DeclaredAccessorInfo>::cast( 472 NewStruct(DECLARED_ACCESSOR_INFO_TYPE)); 473 info->set_flag(0); // Must clear the flag, it was initialized as undefined. 474 return info; 475 } 476 477 478 Handle<ExecutableAccessorInfo> Factory::NewExecutableAccessorInfo() { 479 Handle<ExecutableAccessorInfo> info = 480 Handle<ExecutableAccessorInfo>::cast( 481 NewStruct(EXECUTABLE_ACCESSOR_INFO_TYPE)); 482 info->set_flag(0); // Must clear the flag, it was initialized as undefined. 483 return info; 484 } 485 486 487 Handle<Script> Factory::NewScript(Handle<String> source) { 488 // Generate id for this script. 489 Heap* heap = isolate()->heap(); 490 int id = heap->last_script_id()->value() + 1; 491 if (!Smi::IsValid(id) || id < 0) id = 1; 492 heap->set_last_script_id(Smi::FromInt(id)); 493 494 // Create and initialize script object. 495 Handle<Foreign> wrapper = NewForeign(0, TENURED); 496 Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE)); 497 script->set_source(*source); 498 script->set_name(heap->undefined_value()); 499 script->set_id(Smi::FromInt(id)); 500 script->set_line_offset(Smi::FromInt(0)); 501 script->set_column_offset(Smi::FromInt(0)); 502 script->set_data(heap->undefined_value()); 503 script->set_context_data(heap->undefined_value()); 504 script->set_type(Smi::FromInt(Script::TYPE_NORMAL)); 505 script->set_wrapper(*wrapper); 506 script->set_line_ends(heap->undefined_value()); 507 script->set_eval_from_shared(heap->undefined_value()); 508 script->set_eval_from_instructions_offset(Smi::FromInt(0)); 509 script->set_flags(Smi::FromInt(0)); 510 511 return script; 512 } 513 514 515 Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) { 516 CALL_HEAP_FUNCTION(isolate(), 517 isolate()->heap()->AllocateForeign(addr, pretenure), 518 Foreign); 519 } 520 521 522 Handle<Foreign> Factory::NewForeign(const AccessorDescriptor* desc) { 523 return NewForeign((Address) desc, TENURED); 524 } 525 526 527 Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) { 528 ASSERT(0 <= length); 529 CALL_HEAP_FUNCTION( 530 isolate(), 531 isolate()->heap()->AllocateByteArray(length, pretenure), 532 ByteArray); 533 } 534 535 536 Handle<ExternalArray> Factory::NewExternalArray(int length, 537 ExternalArrayType array_type, 538 void* external_pointer, 539 PretenureFlag pretenure) { 540 ASSERT(0 <= length); 541 CALL_HEAP_FUNCTION( 542 isolate(), 543 isolate()->heap()->AllocateExternalArray(length, 544 array_type, 545 external_pointer, 546 pretenure), 547 ExternalArray); 548 } 549 550 551 Handle<Cell> Factory::NewCell(Handle<Object> value) { 552 AllowDeferredHandleDereference convert_to_cell; 553 CALL_HEAP_FUNCTION( 554 isolate(), 555 isolate()->heap()->AllocateCell(*value), 556 Cell); 557 } 558 559 560 Handle<PropertyCell> Factory::NewPropertyCellWithHole() { 561 CALL_HEAP_FUNCTION( 562 isolate(), 563 isolate()->heap()->AllocatePropertyCell(), 564 PropertyCell); 565 } 566 567 568 Handle<PropertyCell> Factory::NewPropertyCell(Handle<Object> value) { 569 AllowDeferredHandleDereference convert_to_cell; 570 Handle<PropertyCell> cell = NewPropertyCellWithHole(); 571 PropertyCell::SetValueInferType(cell, value); 572 return cell; 573 } 574 575 576 Handle<AllocationSite> Factory::NewAllocationSite() { 577 CALL_HEAP_FUNCTION( 578 isolate(), 579 isolate()->heap()->AllocateAllocationSite(), 580 AllocationSite); 581 } 582 583 584 Handle<Map> Factory::NewMap(InstanceType type, 585 int instance_size, 586 ElementsKind elements_kind) { 587 CALL_HEAP_FUNCTION( 588 isolate(), 589 isolate()->heap()->AllocateMap(type, instance_size, elements_kind), 590 Map); 591 } 592 593 594 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) { 595 // Make sure to use globals from the function's context, since the function 596 // can be from a different context. 597 Handle<Context> native_context(function->context()->native_context()); 598 Handle<Map> new_map; 599 if (function->shared()->is_generator()) { 600 // Generator prototypes can share maps since they don't have "constructor" 601 // properties. 602 new_map = handle(native_context->generator_object_prototype_map()); 603 } else { 604 // Each function prototype gets a fresh map to avoid unwanted sharing of 605 // maps between prototypes of different constructors. 606 Handle<JSFunction> object_function(native_context->object_function()); 607 ASSERT(object_function->has_initial_map()); 608 new_map = Map::Copy(handle(object_function->initial_map())); 609 } 610 611 Handle<JSObject> prototype = NewJSObjectFromMap(new_map); 612 613 if (!function->shared()->is_generator()) { 614 JSObject::SetLocalPropertyIgnoreAttributes(prototype, 615 constructor_string(), 616 function, 617 DONT_ENUM); 618 } 619 620 return prototype; 621 } 622 623 624 Handle<Map> Factory::CopyWithPreallocatedFieldDescriptors(Handle<Map> src) { 625 CALL_HEAP_FUNCTION( 626 isolate(), src->CopyWithPreallocatedFieldDescriptors(), Map); 627 } 628 629 630 Handle<Map> Factory::CopyMap(Handle<Map> src, 631 int extra_inobject_properties) { 632 Handle<Map> copy = CopyWithPreallocatedFieldDescriptors(src); 633 // Check that we do not overflow the instance size when adding the 634 // extra inobject properties. 635 int instance_size_delta = extra_inobject_properties * kPointerSize; 636 int max_instance_size_delta = 637 JSObject::kMaxInstanceSize - copy->instance_size(); 638 int max_extra_properties = max_instance_size_delta >> kPointerSizeLog2; 639 if (extra_inobject_properties > max_extra_properties) { 640 // If the instance size overflows, we allocate as many properties 641 // as we can as inobject properties. 642 instance_size_delta = max_instance_size_delta; 643 extra_inobject_properties = max_extra_properties; 644 } 645 // Adjust the map with the extra inobject properties. 646 int inobject_properties = 647 copy->inobject_properties() + extra_inobject_properties; 648 copy->set_inobject_properties(inobject_properties); 649 copy->set_unused_property_fields(inobject_properties); 650 copy->set_instance_size(copy->instance_size() + instance_size_delta); 651 copy->set_visitor_id(StaticVisitorBase::GetVisitorId(*copy)); 652 return copy; 653 } 654 655 656 Handle<Map> Factory::CopyMap(Handle<Map> src) { 657 CALL_HEAP_FUNCTION(isolate(), src->Copy(), Map); 658 } 659 660 661 Handle<Map> Factory::GetElementsTransitionMap( 662 Handle<JSObject> src, 663 ElementsKind elements_kind) { 664 Isolate* i = isolate(); 665 CALL_HEAP_FUNCTION(i, 666 src->GetElementsTransitionMap(i, elements_kind), 667 Map); 668 } 669 670 671 Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) { 672 CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedArray); 673 } 674 675 676 Handle<FixedArray> Factory::CopySizeFixedArray(Handle<FixedArray> array, 677 int new_length, 678 PretenureFlag pretenure) { 679 CALL_HEAP_FUNCTION(isolate(), 680 array->CopySize(new_length, pretenure), 681 FixedArray); 682 } 683 684 685 Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray( 686 Handle<FixedDoubleArray> array) { 687 CALL_HEAP_FUNCTION(isolate(), array->Copy(), FixedDoubleArray); 688 } 689 690 691 Handle<ConstantPoolArray> Factory::CopyConstantPoolArray( 692 Handle<ConstantPoolArray> array) { 693 CALL_HEAP_FUNCTION(isolate(), array->Copy(), ConstantPoolArray); 694 } 695 696 697 Handle<JSFunction> Factory::BaseNewFunctionFromSharedFunctionInfo( 698 Handle<SharedFunctionInfo> function_info, 699 Handle<Map> function_map, 700 PretenureFlag pretenure) { 701 CALL_HEAP_FUNCTION( 702 isolate(), 703 isolate()->heap()->AllocateFunction(*function_map, 704 *function_info, 705 isolate()->heap()->the_hole_value(), 706 pretenure), 707 JSFunction); 708 } 709 710 711 static Handle<Map> MapForNewFunction(Isolate *isolate, 712 Handle<SharedFunctionInfo> function_info) { 713 Context *context = isolate->context()->native_context(); 714 int map_index = Context::FunctionMapIndex(function_info->language_mode(), 715 function_info->is_generator()); 716 return Handle<Map>(Map::cast(context->get(map_index))); 717 } 718 719 720 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( 721 Handle<SharedFunctionInfo> function_info, 722 Handle<Context> context, 723 PretenureFlag pretenure) { 724 Handle<JSFunction> result = BaseNewFunctionFromSharedFunctionInfo( 725 function_info, 726 MapForNewFunction(isolate(), function_info), 727 pretenure); 728 729 if (function_info->ic_age() != isolate()->heap()->global_ic_age()) { 730 function_info->ResetForNewContext(isolate()->heap()->global_ic_age()); 731 } 732 733 result->set_context(*context); 734 735 int index = function_info->SearchOptimizedCodeMap(context->native_context()); 736 if (!function_info->bound() && index < 0) { 737 int number_of_literals = function_info->num_literals(); 738 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure); 739 if (number_of_literals > 0) { 740 // Store the native context in the literals array prefix. This 741 // context will be used when creating object, regexp and array 742 // literals in this function. 743 literals->set(JSFunction::kLiteralNativeContextIndex, 744 context->native_context()); 745 } 746 result->set_literals(*literals); 747 } 748 749 if (index > 0) { 750 // Caching of optimized code enabled and optimized code found. 751 function_info->InstallFromOptimizedCodeMap(*result, index); 752 return result; 753 } 754 755 if (isolate()->use_crankshaft() && 756 FLAG_always_opt && 757 result->is_compiled() && 758 !function_info->is_toplevel() && 759 function_info->allows_lazy_compilation() && 760 !function_info->optimization_disabled() && 761 !isolate()->DebuggerHasBreakPoints()) { 762 result->MarkForLazyRecompilation(); 763 } 764 return result; 765 } 766 767 768 Handle<Object> Factory::NewNumber(double value, 769 PretenureFlag pretenure) { 770 CALL_HEAP_FUNCTION( 771 isolate(), 772 isolate()->heap()->NumberFromDouble(value, pretenure), Object); 773 } 774 775 776 Handle<Object> Factory::NewNumberFromInt(int32_t value, 777 PretenureFlag pretenure) { 778 CALL_HEAP_FUNCTION( 779 isolate(), 780 isolate()->heap()->NumberFromInt32(value, pretenure), Object); 781 } 782 783 784 Handle<Object> Factory::NewNumberFromUint(uint32_t value, 785 PretenureFlag pretenure) { 786 CALL_HEAP_FUNCTION( 787 isolate(), 788 isolate()->heap()->NumberFromUint32(value, pretenure), Object); 789 } 790 791 792 Handle<HeapNumber> Factory::NewHeapNumber(double value, 793 PretenureFlag pretenure) { 794 CALL_HEAP_FUNCTION( 795 isolate(), 796 isolate()->heap()->AllocateHeapNumber(value, pretenure), HeapNumber); 797 } 798 799 800 Handle<JSObject> Factory::NewNeanderObject() { 801 CALL_HEAP_FUNCTION( 802 isolate(), 803 isolate()->heap()->AllocateJSObjectFromMap( 804 isolate()->heap()->neander_map()), 805 JSObject); 806 } 807 808 809 Handle<Object> Factory::NewTypeError(const char* message, 810 Vector< Handle<Object> > args) { 811 return NewError("MakeTypeError", message, args); 812 } 813 814 815 Handle<Object> Factory::NewTypeError(Handle<String> message) { 816 return NewError("$TypeError", message); 817 } 818 819 820 Handle<Object> Factory::NewRangeError(const char* message, 821 Vector< Handle<Object> > args) { 822 return NewError("MakeRangeError", message, args); 823 } 824 825 826 Handle<Object> Factory::NewRangeError(Handle<String> message) { 827 return NewError("$RangeError", message); 828 } 829 830 831 Handle<Object> Factory::NewSyntaxError(const char* message, 832 Handle<JSArray> args) { 833 return NewError("MakeSyntaxError", message, args); 834 } 835 836 837 Handle<Object> Factory::NewSyntaxError(Handle<String> message) { 838 return NewError("$SyntaxError", message); 839 } 840 841 842 Handle<Object> Factory::NewReferenceError(const char* message, 843 Vector< Handle<Object> > args) { 844 return NewError("MakeReferenceError", message, args); 845 } 846 847 848 Handle<Object> Factory::NewReferenceError(Handle<String> message) { 849 return NewError("$ReferenceError", message); 850 } 851 852 853 Handle<Object> Factory::NewError(const char* maker, 854 const char* message, 855 Vector< Handle<Object> > args) { 856 // Instantiate a closeable HandleScope for EscapeFrom. 857 v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate())); 858 Handle<FixedArray> array = NewFixedArray(args.length()); 859 for (int i = 0; i < args.length(); i++) { 860 array->set(i, *args[i]); 861 } 862 Handle<JSArray> object = NewJSArrayWithElements(array); 863 Handle<Object> result = NewError(maker, message, object); 864 return result.EscapeFrom(&scope); 865 } 866 867 868 Handle<Object> Factory::NewEvalError(const char* message, 869 Vector< Handle<Object> > args) { 870 return NewError("MakeEvalError", message, args); 871 } 872 873 874 Handle<Object> Factory::NewError(const char* message, 875 Vector< Handle<Object> > args) { 876 return NewError("MakeError", message, args); 877 } 878 879 880 Handle<String> Factory::EmergencyNewError(const char* message, 881 Handle<JSArray> args) { 882 const int kBufferSize = 1000; 883 char buffer[kBufferSize]; 884 size_t space = kBufferSize; 885 char* p = &buffer[0]; 886 887 Vector<char> v(buffer, kBufferSize); 888 OS::StrNCpy(v, message, space); 889 space -= Min(space, strlen(message)); 890 p = &buffer[kBufferSize] - space; 891 892 for (unsigned i = 0; i < ARRAY_SIZE(args); i++) { 893 if (space > 0) { 894 *p++ = ' '; 895 space--; 896 if (space > 0) { 897 MaybeObject* maybe_arg = args->GetElement(isolate(), i); 898 Handle<String> arg_str(reinterpret_cast<String*>(maybe_arg)); 899 const char* arg = *arg_str->ToCString(); 900 Vector<char> v2(p, static_cast<int>(space)); 901 OS::StrNCpy(v2, arg, space); 902 space -= Min(space, strlen(arg)); 903 p = &buffer[kBufferSize] - space; 904 } 905 } 906 } 907 if (space > 0) { 908 *p = '\0'; 909 } else { 910 buffer[kBufferSize - 1] = '\0'; 911 } 912 Handle<String> error_string = NewStringFromUtf8(CStrVector(buffer), TENURED); 913 return error_string; 914 } 915 916 917 Handle<Object> Factory::NewError(const char* maker, 918 const char* message, 919 Handle<JSArray> args) { 920 Handle<String> make_str = InternalizeUtf8String(maker); 921 Handle<Object> fun_obj( 922 isolate()->js_builtins_object()->GetPropertyNoExceptionThrown(*make_str), 923 isolate()); 924 // If the builtins haven't been properly configured yet this error 925 // constructor may not have been defined. Bail out. 926 if (!fun_obj->IsJSFunction()) { 927 return EmergencyNewError(message, args); 928 } 929 Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj); 930 Handle<Object> message_obj = InternalizeUtf8String(message); 931 Handle<Object> argv[] = { message_obj, args }; 932 933 // Invoke the JavaScript factory method. If an exception is thrown while 934 // running the factory method, use the exception as the result. 935 bool caught_exception; 936 Handle<Object> result = Execution::TryCall(fun, 937 isolate()->js_builtins_object(), 938 ARRAY_SIZE(argv), 939 argv, 940 &caught_exception); 941 return result; 942 } 943 944 945 Handle<Object> Factory::NewError(Handle<String> message) { 946 return NewError("$Error", message); 947 } 948 949 950 Handle<Object> Factory::NewError(const char* constructor, 951 Handle<String> message) { 952 Handle<String> constr = InternalizeUtf8String(constructor); 953 Handle<JSFunction> fun = Handle<JSFunction>( 954 JSFunction::cast(isolate()->js_builtins_object()-> 955 GetPropertyNoExceptionThrown(*constr))); 956 Handle<Object> argv[] = { message }; 957 958 // Invoke the JavaScript factory method. If an exception is thrown while 959 // running the factory method, use the exception as the result. 960 bool caught_exception; 961 Handle<Object> result = Execution::TryCall(fun, 962 isolate()->js_builtins_object(), 963 ARRAY_SIZE(argv), 964 argv, 965 &caught_exception); 966 return result; 967 } 968 969 970 Handle<JSFunction> Factory::NewFunction(Handle<String> name, 971 InstanceType type, 972 int instance_size, 973 Handle<Code> code, 974 bool force_initial_map) { 975 // Allocate the function 976 Handle<JSFunction> function = NewFunction(name, the_hole_value()); 977 978 // Set up the code pointer in both the shared function info and in 979 // the function itself. 980 function->shared()->set_code(*code); 981 function->set_code(*code); 982 983 if (force_initial_map || 984 type != JS_OBJECT_TYPE || 985 instance_size != JSObject::kHeaderSize) { 986 Handle<Map> initial_map = NewMap(type, instance_size); 987 Handle<JSObject> prototype = NewFunctionPrototype(function); 988 initial_map->set_prototype(*prototype); 989 function->set_initial_map(*initial_map); 990 initial_map->set_constructor(*function); 991 } else { 992 ASSERT(!function->has_initial_map()); 993 ASSERT(!function->has_prototype()); 994 } 995 996 return function; 997 } 998 999 1000 Handle<JSFunction> Factory::NewFunctionWithPrototype(Handle<String> name, 1001 InstanceType type, 1002 int instance_size, 1003 Handle<JSObject> prototype, 1004 Handle<Code> code, 1005 bool force_initial_map) { 1006 // Allocate the function. 1007 Handle<JSFunction> function = NewFunction(name, prototype); 1008 1009 // Set up the code pointer in both the shared function info and in 1010 // the function itself. 1011 function->shared()->set_code(*code); 1012 function->set_code(*code); 1013 1014 if (force_initial_map || 1015 type != JS_OBJECT_TYPE || 1016 instance_size != JSObject::kHeaderSize) { 1017 Handle<Map> initial_map = NewMap(type, 1018 instance_size, 1019 GetInitialFastElementsKind()); 1020 function->set_initial_map(*initial_map); 1021 initial_map->set_constructor(*function); 1022 } 1023 1024 JSFunction::SetPrototype(function, prototype); 1025 return function; 1026 } 1027 1028 1029 Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name, 1030 Handle<Code> code) { 1031 Handle<JSFunction> function = NewFunctionWithoutPrototype(name, 1032 CLASSIC_MODE); 1033 function->shared()->set_code(*code); 1034 function->set_code(*code); 1035 ASSERT(!function->has_initial_map()); 1036 ASSERT(!function->has_prototype()); 1037 return function; 1038 } 1039 1040 1041 Handle<ScopeInfo> Factory::NewScopeInfo(int length) { 1042 CALL_HEAP_FUNCTION( 1043 isolate(), 1044 isolate()->heap()->AllocateScopeInfo(length), 1045 ScopeInfo); 1046 } 1047 1048 1049 Handle<JSObject> Factory::NewExternal(void* value) { 1050 CALL_HEAP_FUNCTION(isolate(), 1051 isolate()->heap()->AllocateExternal(value), 1052 JSObject); 1053 } 1054 1055 1056 Handle<Code> Factory::NewCode(const CodeDesc& desc, 1057 Code::Flags flags, 1058 Handle<Object> self_ref, 1059 bool immovable, 1060 bool crankshafted, 1061 int prologue_offset) { 1062 CALL_HEAP_FUNCTION(isolate(), 1063 isolate()->heap()->CreateCode( 1064 desc, flags, self_ref, immovable, crankshafted, 1065 prologue_offset), 1066 Code); 1067 } 1068 1069 1070 Handle<Code> Factory::CopyCode(Handle<Code> code) { 1071 CALL_HEAP_FUNCTION(isolate(), 1072 isolate()->heap()->CopyCode(*code), 1073 Code); 1074 } 1075 1076 1077 Handle<Code> Factory::CopyCode(Handle<Code> code, Vector<byte> reloc_info) { 1078 CALL_HEAP_FUNCTION(isolate(), 1079 isolate()->heap()->CopyCode(*code, reloc_info), 1080 Code); 1081 } 1082 1083 1084 Handle<String> Factory::InternalizedStringFromString(Handle<String> value) { 1085 CALL_HEAP_FUNCTION(isolate(), 1086 isolate()->heap()->InternalizeString(*value), String); 1087 } 1088 1089 1090 Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, 1091 PretenureFlag pretenure) { 1092 JSFunction::EnsureHasInitialMap(constructor); 1093 CALL_HEAP_FUNCTION( 1094 isolate(), 1095 isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); 1096 } 1097 1098 1099 Handle<JSModule> Factory::NewJSModule(Handle<Context> context, 1100 Handle<ScopeInfo> scope_info) { 1101 CALL_HEAP_FUNCTION( 1102 isolate(), 1103 isolate()->heap()->AllocateJSModule(*context, *scope_info), JSModule); 1104 } 1105 1106 1107 // TODO(mstarzinger): Temporary wrapper until handlified. 1108 static Handle<NameDictionary> NameDictionaryAdd(Handle<NameDictionary> dict, 1109 Handle<Name> name, 1110 Handle<Object> value, 1111 PropertyDetails details) { 1112 CALL_HEAP_FUNCTION(dict->GetIsolate(), 1113 dict->Add(*name, *value, details), 1114 NameDictionary); 1115 } 1116 1117 1118 static Handle<GlobalObject> NewGlobalObjectFromMap(Isolate* isolate, 1119 Handle<Map> map) { 1120 CALL_HEAP_FUNCTION(isolate, 1121 isolate->heap()->Allocate(*map, OLD_POINTER_SPACE), 1122 GlobalObject); 1123 } 1124 1125 1126 Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) { 1127 ASSERT(constructor->has_initial_map()); 1128 Handle<Map> map(constructor->initial_map()); 1129 ASSERT(map->is_dictionary_map()); 1130 1131 // Make sure no field properties are described in the initial map. 1132 // This guarantees us that normalizing the properties does not 1133 // require us to change property values to PropertyCells. 1134 ASSERT(map->NextFreePropertyIndex() == 0); 1135 1136 // Make sure we don't have a ton of pre-allocated slots in the 1137 // global objects. They will be unused once we normalize the object. 1138 ASSERT(map->unused_property_fields() == 0); 1139 ASSERT(map->inobject_properties() == 0); 1140 1141 // Initial size of the backing store to avoid resize of the storage during 1142 // bootstrapping. The size differs between the JS global object ad the 1143 // builtins object. 1144 int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512; 1145 1146 // Allocate a dictionary object for backing storage. 1147 int at_least_space_for = map->NumberOfOwnDescriptors() * 2 + initial_size; 1148 Handle<NameDictionary> dictionary = NewNameDictionary(at_least_space_for); 1149 1150 // The global object might be created from an object template with accessors. 1151 // Fill these accessors into the dictionary. 1152 Handle<DescriptorArray> descs(map->instance_descriptors()); 1153 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { 1154 PropertyDetails details = descs->GetDetails(i); 1155 ASSERT(details.type() == CALLBACKS); // Only accessors are expected. 1156 PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i + 1); 1157 Handle<Name> name(descs->GetKey(i)); 1158 Handle<Object> value(descs->GetCallbacksObject(i), isolate()); 1159 Handle<PropertyCell> cell = NewPropertyCell(value); 1160 NameDictionaryAdd(dictionary, name, cell, d); 1161 } 1162 1163 // Allocate the global object and initialize it with the backing store. 1164 Handle<GlobalObject> global = NewGlobalObjectFromMap(isolate(), map); 1165 isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map); 1166 1167 // Create a new map for the global object. 1168 Handle<Map> new_map = Map::CopyDropDescriptors(map); 1169 new_map->set_dictionary_map(true); 1170 1171 // Set up the global object as a normalized object. 1172 global->set_map(*new_map); 1173 global->set_properties(*dictionary); 1174 1175 // Make sure result is a global object with properties in dictionary. 1176 ASSERT(global->IsGlobalObject() && !global->HasFastProperties()); 1177 return global; 1178 } 1179 1180 1181 Handle<JSObject> Factory::NewJSObjectFromMap(Handle<Map> map, 1182 PretenureFlag pretenure, 1183 bool alloc_props) { 1184 CALL_HEAP_FUNCTION( 1185 isolate(), 1186 isolate()->heap()->AllocateJSObjectFromMap(*map, pretenure, alloc_props), 1187 JSObject); 1188 } 1189 1190 1191 Handle<JSArray> Factory::NewJSArray(int capacity, 1192 ElementsKind elements_kind, 1193 PretenureFlag pretenure) { 1194 if (capacity != 0) { 1195 elements_kind = GetHoleyElementsKind(elements_kind); 1196 } 1197 CALL_HEAP_FUNCTION(isolate(), 1198 isolate()->heap()->AllocateJSArrayAndStorage( 1199 elements_kind, 1200 0, 1201 capacity, 1202 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, 1203 pretenure), 1204 JSArray); 1205 } 1206 1207 1208 Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements, 1209 ElementsKind elements_kind, 1210 PretenureFlag pretenure) { 1211 CALL_HEAP_FUNCTION( 1212 isolate(), 1213 isolate()->heap()->AllocateJSArrayWithElements(*elements, 1214 elements_kind, 1215 elements->length(), 1216 pretenure), 1217 JSArray); 1218 } 1219 1220 1221 void Factory::SetElementsCapacityAndLength(Handle<JSArray> array, 1222 int capacity, 1223 int length) { 1224 ElementsAccessor* accessor = array->GetElementsAccessor(); 1225 CALL_HEAP_FUNCTION_VOID( 1226 isolate(), 1227 accessor->SetCapacityAndLength(*array, capacity, length)); 1228 } 1229 1230 1231 void Factory::SetContent(Handle<JSArray> array, 1232 Handle<FixedArrayBase> elements) { 1233 CALL_HEAP_FUNCTION_VOID( 1234 isolate(), 1235 array->SetContent(*elements)); 1236 } 1237 1238 1239 Handle<JSGeneratorObject> Factory::NewJSGeneratorObject( 1240 Handle<JSFunction> function) { 1241 ASSERT(function->shared()->is_generator()); 1242 JSFunction::EnsureHasInitialMap(function); 1243 Handle<Map> map(function->initial_map()); 1244 ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE); 1245 CALL_HEAP_FUNCTION( 1246 isolate(), 1247 isolate()->heap()->AllocateJSObjectFromMap(*map), 1248 JSGeneratorObject); 1249 } 1250 1251 1252 Handle<JSArrayBuffer> Factory::NewJSArrayBuffer() { 1253 Handle<JSFunction> array_buffer_fun( 1254 isolate()->context()->native_context()->array_buffer_fun()); 1255 CALL_HEAP_FUNCTION( 1256 isolate(), 1257 isolate()->heap()->AllocateJSObject(*array_buffer_fun), 1258 JSArrayBuffer); 1259 } 1260 1261 1262 Handle<JSDataView> Factory::NewJSDataView() { 1263 Handle<JSFunction> data_view_fun( 1264 isolate()->context()->native_context()->data_view_fun()); 1265 CALL_HEAP_FUNCTION( 1266 isolate(), 1267 isolate()->heap()->AllocateJSObject(*data_view_fun), 1268 JSDataView); 1269 } 1270 1271 1272 static JSFunction* GetTypedArrayFun(ExternalArrayType type, 1273 Isolate* isolate) { 1274 Context* native_context = isolate->context()->native_context(); 1275 switch (type) { 1276 case kExternalUnsignedByteArray: 1277 return native_context->uint8_array_fun(); 1278 1279 case kExternalByteArray: 1280 return native_context->int8_array_fun(); 1281 1282 case kExternalUnsignedShortArray: 1283 return native_context->uint16_array_fun(); 1284 1285 case kExternalShortArray: 1286 return native_context->int16_array_fun(); 1287 1288 case kExternalUnsignedIntArray: 1289 return native_context->uint32_array_fun(); 1290 1291 case kExternalIntArray: 1292 return native_context->int32_array_fun(); 1293 1294 case kExternalFloatArray: 1295 return native_context->float_array_fun(); 1296 1297 case kExternalDoubleArray: 1298 return native_context->double_array_fun(); 1299 1300 case kExternalPixelArray: 1301 return native_context->uint8c_array_fun(); 1302 1303 default: 1304 UNREACHABLE(); 1305 return NULL; 1306 } 1307 } 1308 1309 1310 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) { 1311 Handle<JSFunction> typed_array_fun_handle(GetTypedArrayFun(type, isolate())); 1312 1313 CALL_HEAP_FUNCTION( 1314 isolate(), 1315 isolate()->heap()->AllocateJSObject(*typed_array_fun_handle), 1316 JSTypedArray); 1317 } 1318 1319 1320 Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler, 1321 Handle<Object> prototype) { 1322 CALL_HEAP_FUNCTION( 1323 isolate(), 1324 isolate()->heap()->AllocateJSProxy(*handler, *prototype), 1325 JSProxy); 1326 } 1327 1328 1329 void Factory::BecomeJSObject(Handle<JSReceiver> object) { 1330 CALL_HEAP_FUNCTION_VOID( 1331 isolate(), 1332 isolate()->heap()->ReinitializeJSReceiver( 1333 *object, JS_OBJECT_TYPE, JSObject::kHeaderSize)); 1334 } 1335 1336 1337 void Factory::BecomeJSFunction(Handle<JSReceiver> object) { 1338 CALL_HEAP_FUNCTION_VOID( 1339 isolate(), 1340 isolate()->heap()->ReinitializeJSReceiver( 1341 *object, JS_FUNCTION_TYPE, JSFunction::kSize)); 1342 } 1343 1344 1345 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( 1346 Handle<String> name, 1347 int number_of_literals, 1348 bool is_generator, 1349 Handle<Code> code, 1350 Handle<ScopeInfo> scope_info) { 1351 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name); 1352 shared->set_code(*code); 1353 shared->set_scope_info(*scope_info); 1354 int literals_array_size = number_of_literals; 1355 // If the function contains object, regexp or array literals, 1356 // allocate extra space for a literals array prefix containing the 1357 // context. 1358 if (number_of_literals > 0) { 1359 literals_array_size += JSFunction::kLiteralsPrefixSize; 1360 } 1361 shared->set_num_literals(literals_array_size); 1362 if (is_generator) { 1363 shared->set_instance_class_name(isolate()->heap()->Generator_string()); 1364 shared->DisableOptimization(kGenerator); 1365 } 1366 return shared; 1367 } 1368 1369 1370 Handle<JSMessageObject> Factory::NewJSMessageObject( 1371 Handle<String> type, 1372 Handle<JSArray> arguments, 1373 int start_position, 1374 int end_position, 1375 Handle<Object> script, 1376 Handle<Object> stack_trace, 1377 Handle<Object> stack_frames) { 1378 CALL_HEAP_FUNCTION(isolate(), 1379 isolate()->heap()->AllocateJSMessageObject(*type, 1380 *arguments, 1381 start_position, 1382 end_position, 1383 *script, 1384 *stack_trace, 1385 *stack_frames), 1386 JSMessageObject); 1387 } 1388 1389 1390 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) { 1391 CALL_HEAP_FUNCTION(isolate(), 1392 isolate()->heap()->AllocateSharedFunctionInfo(*name), 1393 SharedFunctionInfo); 1394 } 1395 1396 1397 Handle<String> Factory::NumberToString(Handle<Object> number) { 1398 CALL_HEAP_FUNCTION(isolate(), 1399 isolate()->heap()->NumberToString(*number), String); 1400 } 1401 1402 1403 Handle<String> Factory::Uint32ToString(uint32_t value) { 1404 CALL_HEAP_FUNCTION(isolate(), 1405 isolate()->heap()->Uint32ToString(value), String); 1406 } 1407 1408 1409 Handle<SeededNumberDictionary> Factory::DictionaryAtNumberPut( 1410 Handle<SeededNumberDictionary> dictionary, 1411 uint32_t key, 1412 Handle<Object> value) { 1413 CALL_HEAP_FUNCTION(isolate(), 1414 dictionary->AtNumberPut(key, *value), 1415 SeededNumberDictionary); 1416 } 1417 1418 1419 Handle<UnseededNumberDictionary> Factory::DictionaryAtNumberPut( 1420 Handle<UnseededNumberDictionary> dictionary, 1421 uint32_t key, 1422 Handle<Object> value) { 1423 CALL_HEAP_FUNCTION(isolate(), 1424 dictionary->AtNumberPut(key, *value), 1425 UnseededNumberDictionary); 1426 } 1427 1428 1429 Handle<JSFunction> Factory::NewFunctionHelper(Handle<String> name, 1430 Handle<Object> prototype) { 1431 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name); 1432 CALL_HEAP_FUNCTION( 1433 isolate(), 1434 isolate()->heap()->AllocateFunction(*isolate()->function_map(), 1435 *function_share, 1436 *prototype), 1437 JSFunction); 1438 } 1439 1440 1441 Handle<JSFunction> Factory::NewFunction(Handle<String> name, 1442 Handle<Object> prototype) { 1443 Handle<JSFunction> fun = NewFunctionHelper(name, prototype); 1444 fun->set_context(isolate()->context()->native_context()); 1445 return fun; 1446 } 1447 1448 1449 Handle<JSFunction> Factory::NewFunctionWithoutPrototypeHelper( 1450 Handle<String> name, 1451 LanguageMode language_mode) { 1452 Handle<SharedFunctionInfo> function_share = NewSharedFunctionInfo(name); 1453 Handle<Map> map = (language_mode == CLASSIC_MODE) 1454 ? isolate()->function_without_prototype_map() 1455 : isolate()->strict_mode_function_without_prototype_map(); 1456 CALL_HEAP_FUNCTION(isolate(), 1457 isolate()->heap()->AllocateFunction( 1458 *map, 1459 *function_share, 1460 *the_hole_value()), 1461 JSFunction); 1462 } 1463 1464 1465 Handle<JSFunction> Factory::NewFunctionWithoutPrototype( 1466 Handle<String> name, 1467 LanguageMode language_mode) { 1468 Handle<JSFunction> fun = 1469 NewFunctionWithoutPrototypeHelper(name, language_mode); 1470 fun->set_context(isolate()->context()->native_context()); 1471 return fun; 1472 } 1473 1474 1475 Handle<Object> Factory::ToObject(Handle<Object> object) { 1476 CALL_HEAP_FUNCTION(isolate(), object->ToObject(isolate()), Object); 1477 } 1478 1479 1480 Handle<Object> Factory::ToObject(Handle<Object> object, 1481 Handle<Context> native_context) { 1482 CALL_HEAP_FUNCTION(isolate(), object->ToObject(*native_context), Object); 1483 } 1484 1485 1486 #ifdef ENABLE_DEBUGGER_SUPPORT 1487 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { 1488 // Get the original code of the function. 1489 Handle<Code> code(shared->code()); 1490 1491 // Create a copy of the code before allocating the debug info object to avoid 1492 // allocation while setting up the debug info object. 1493 Handle<Code> original_code(*Factory::CopyCode(code)); 1494 1495 // Allocate initial fixed array for active break points before allocating the 1496 // debug info object to avoid allocation while setting up the debug info 1497 // object. 1498 Handle<FixedArray> break_points( 1499 NewFixedArray(Debug::kEstimatedNofBreakPointsInFunction)); 1500 1501 // Create and set up the debug info object. Debug info contains function, a 1502 // copy of the original code, the executing code and initial fixed array for 1503 // active break points. 1504 Handle<DebugInfo> debug_info = 1505 Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE)); 1506 debug_info->set_shared(*shared); 1507 debug_info->set_original_code(*original_code); 1508 debug_info->set_code(*code); 1509 debug_info->set_break_points(*break_points); 1510 1511 // Link debug info to function. 1512 shared->set_debug_info(*debug_info); 1513 1514 return debug_info; 1515 } 1516 #endif 1517 1518 1519 Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee, 1520 int length) { 1521 CALL_HEAP_FUNCTION( 1522 isolate(), 1523 isolate()->heap()->AllocateArgumentsObject(*callee, length), JSObject); 1524 } 1525 1526 1527 Handle<JSFunction> Factory::CreateApiFunction( 1528 Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) { 1529 Handle<Code> code = isolate()->builtins()->HandleApiCall(); 1530 Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi(); 1531 1532 int internal_field_count = 0; 1533 if (!obj->instance_template()->IsUndefined()) { 1534 Handle<ObjectTemplateInfo> instance_template = 1535 Handle<ObjectTemplateInfo>( 1536 ObjectTemplateInfo::cast(obj->instance_template())); 1537 internal_field_count = 1538 Smi::cast(instance_template->internal_field_count())->value(); 1539 } 1540 1541 // TODO(svenpanne) Kill ApiInstanceType and refactor things by generalizing 1542 // JSObject::GetHeaderSize. 1543 int instance_size = kPointerSize * internal_field_count; 1544 InstanceType type; 1545 switch (instance_type) { 1546 case JavaScriptObject: 1547 type = JS_OBJECT_TYPE; 1548 instance_size += JSObject::kHeaderSize; 1549 break; 1550 case InnerGlobalObject: 1551 type = JS_GLOBAL_OBJECT_TYPE; 1552 instance_size += JSGlobalObject::kSize; 1553 break; 1554 case OuterGlobalObject: 1555 type = JS_GLOBAL_PROXY_TYPE; 1556 instance_size += JSGlobalProxy::kSize; 1557 break; 1558 default: 1559 UNREACHABLE(); 1560 type = JS_OBJECT_TYPE; // Keep the compiler happy. 1561 break; 1562 } 1563 1564 Handle<JSFunction> result = 1565 NewFunction(Factory::empty_string(), 1566 type, 1567 instance_size, 1568 code, 1569 true); 1570 1571 // Set length. 1572 result->shared()->set_length(obj->length()); 1573 1574 // Set class name. 1575 Handle<Object> class_name = Handle<Object>(obj->class_name(), isolate()); 1576 if (class_name->IsString()) { 1577 result->shared()->set_instance_class_name(*class_name); 1578 result->shared()->set_name(*class_name); 1579 } 1580 1581 Handle<Map> map = Handle<Map>(result->initial_map()); 1582 1583 // Mark as undetectable if needed. 1584 if (obj->undetectable()) { 1585 map->set_is_undetectable(); 1586 } 1587 1588 // Mark as hidden for the __proto__ accessor if needed. 1589 if (obj->hidden_prototype()) { 1590 map->set_is_hidden_prototype(); 1591 } 1592 1593 // Mark as needs_access_check if needed. 1594 if (obj->needs_access_check()) { 1595 map->set_is_access_check_needed(true); 1596 } 1597 1598 // Set interceptor information in the map. 1599 if (!obj->named_property_handler()->IsUndefined()) { 1600 map->set_has_named_interceptor(); 1601 } 1602 if (!obj->indexed_property_handler()->IsUndefined()) { 1603 map->set_has_indexed_interceptor(); 1604 } 1605 1606 // Set instance call-as-function information in the map. 1607 if (!obj->instance_call_handler()->IsUndefined()) { 1608 map->set_has_instance_call_handler(); 1609 } 1610 1611 result->shared()->set_function_data(*obj); 1612 result->shared()->set_construct_stub(*construct_stub); 1613 result->shared()->DontAdaptArguments(); 1614 1615 // Recursively copy parent instance templates' accessors, 1616 // 'data' may be modified. 1617 int max_number_of_additional_properties = 0; 1618 int max_number_of_static_properties = 0; 1619 FunctionTemplateInfo* info = *obj; 1620 while (true) { 1621 if (!info->instance_template()->IsUndefined()) { 1622 Object* props = 1623 ObjectTemplateInfo::cast( 1624 info->instance_template())->property_accessors(); 1625 if (!props->IsUndefined()) { 1626 Handle<Object> props_handle(props, isolate()); 1627 NeanderArray props_array(props_handle); 1628 max_number_of_additional_properties += props_array.length(); 1629 } 1630 } 1631 if (!info->property_accessors()->IsUndefined()) { 1632 Object* props = info->property_accessors(); 1633 if (!props->IsUndefined()) { 1634 Handle<Object> props_handle(props, isolate()); 1635 NeanderArray props_array(props_handle); 1636 max_number_of_static_properties += props_array.length(); 1637 } 1638 } 1639 Object* parent = info->parent_template(); 1640 if (parent->IsUndefined()) break; 1641 info = FunctionTemplateInfo::cast(parent); 1642 } 1643 1644 Map::EnsureDescriptorSlack(map, max_number_of_additional_properties); 1645 1646 // Use a temporary FixedArray to acculumate static accessors 1647 int valid_descriptors = 0; 1648 Handle<FixedArray> array; 1649 if (max_number_of_static_properties > 0) { 1650 array = NewFixedArray(max_number_of_static_properties); 1651 } 1652 1653 while (true) { 1654 // Install instance descriptors 1655 if (!obj->instance_template()->IsUndefined()) { 1656 Handle<ObjectTemplateInfo> instance = 1657 Handle<ObjectTemplateInfo>( 1658 ObjectTemplateInfo::cast(obj->instance_template()), isolate()); 1659 Handle<Object> props = Handle<Object>(instance->property_accessors(), 1660 isolate()); 1661 if (!props->IsUndefined()) { 1662 Map::AppendCallbackDescriptors(map, props); 1663 } 1664 } 1665 // Accumulate static accessors 1666 if (!obj->property_accessors()->IsUndefined()) { 1667 Handle<Object> props = Handle<Object>(obj->property_accessors(), 1668 isolate()); 1669 valid_descriptors = 1670 AccessorInfo::AppendUnique(props, array, valid_descriptors); 1671 } 1672 // Climb parent chain 1673 Handle<Object> parent = Handle<Object>(obj->parent_template(), isolate()); 1674 if (parent->IsUndefined()) break; 1675 obj = Handle<FunctionTemplateInfo>::cast(parent); 1676 } 1677 1678 // Install accumulated static accessors 1679 for (int i = 0; i < valid_descriptors; i++) { 1680 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); 1681 JSObject::SetAccessor(result, accessor); 1682 } 1683 1684 ASSERT(result->shared()->IsApiFunction()); 1685 return result; 1686 } 1687 1688 1689 Handle<MapCache> Factory::NewMapCache(int at_least_space_for) { 1690 CALL_HEAP_FUNCTION(isolate(), 1691 MapCache::Allocate(isolate()->heap(), 1692 at_least_space_for), 1693 MapCache); 1694 } 1695 1696 1697 MUST_USE_RESULT static MaybeObject* UpdateMapCacheWith(Context* context, 1698 FixedArray* keys, 1699 Map* map) { 1700 Object* result; 1701 { MaybeObject* maybe_result = 1702 MapCache::cast(context->map_cache())->Put(keys, map); 1703 if (!maybe_result->ToObject(&result)) return maybe_result; 1704 } 1705 context->set_map_cache(MapCache::cast(result)); 1706 return result; 1707 } 1708 1709 1710 Handle<MapCache> Factory::AddToMapCache(Handle<Context> context, 1711 Handle<FixedArray> keys, 1712 Handle<Map> map) { 1713 CALL_HEAP_FUNCTION(isolate(), 1714 UpdateMapCacheWith(*context, *keys, *map), MapCache); 1715 } 1716 1717 1718 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context, 1719 Handle<FixedArray> keys) { 1720 if (context->map_cache()->IsUndefined()) { 1721 // Allocate the new map cache for the native context. 1722 Handle<MapCache> new_cache = NewMapCache(24); 1723 context->set_map_cache(*new_cache); 1724 } 1725 // Check to see whether there is a matching element in the cache. 1726 Handle<MapCache> cache = 1727 Handle<MapCache>(MapCache::cast(context->map_cache())); 1728 Handle<Object> result = Handle<Object>(cache->Lookup(*keys), isolate()); 1729 if (result->IsMap()) return Handle<Map>::cast(result); 1730 // Create a new map and add it to the cache. 1731 Handle<Map> map = 1732 CopyMap(Handle<Map>(context->object_function()->initial_map()), 1733 keys->length()); 1734 AddToMapCache(context, keys, map); 1735 return Handle<Map>(map); 1736 } 1737 1738 1739 void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp, 1740 JSRegExp::Type type, 1741 Handle<String> source, 1742 JSRegExp::Flags flags, 1743 Handle<Object> data) { 1744 Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize); 1745 1746 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); 1747 store->set(JSRegExp::kSourceIndex, *source); 1748 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value())); 1749 store->set(JSRegExp::kAtomPatternIndex, *data); 1750 regexp->set_data(*store); 1751 } 1752 1753 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, 1754 JSRegExp::Type type, 1755 Handle<String> source, 1756 JSRegExp::Flags flags, 1757 int capture_count) { 1758 Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize); 1759 Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue); 1760 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); 1761 store->set(JSRegExp::kSourceIndex, *source); 1762 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value())); 1763 store->set(JSRegExp::kIrregexpASCIICodeIndex, uninitialized); 1764 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); 1765 store->set(JSRegExp::kIrregexpASCIICodeSavedIndex, uninitialized); 1766 store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); 1767 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0)); 1768 store->set(JSRegExp::kIrregexpCaptureCountIndex, 1769 Smi::FromInt(capture_count)); 1770 regexp->set_data(*store); 1771 } 1772 1773 1774 1775 void Factory::ConfigureInstance(Handle<FunctionTemplateInfo> desc, 1776 Handle<JSObject> instance, 1777 bool* pending_exception) { 1778 // Configure the instance by adding the properties specified by the 1779 // instance template. 1780 Handle<Object> instance_template(desc->instance_template(), isolate()); 1781 if (!instance_template->IsUndefined()) { 1782 Execution::ConfigureInstance(isolate(), 1783 instance, 1784 instance_template, 1785 pending_exception); 1786 } else { 1787 *pending_exception = false; 1788 } 1789 } 1790 1791 1792 Handle<Object> Factory::GlobalConstantFor(Handle<String> name) { 1793 Heap* h = isolate()->heap(); 1794 if (name->Equals(h->undefined_string())) return undefined_value(); 1795 if (name->Equals(h->nan_string())) return nan_value(); 1796 if (name->Equals(h->infinity_string())) return infinity_value(); 1797 return Handle<Object>::null(); 1798 } 1799 1800 1801 Handle<Object> Factory::ToBoolean(bool value) { 1802 return value ? true_value() : false_value(); 1803 } 1804 1805 1806 } } // namespace v8::internal 1807