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