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