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