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