| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 // if args[1] is a data property on args[0] | 630 // if args[1] is a data property on args[0] |
| 631 // [false, value, Writeable, Enumerable, Configurable] | 631 // [false, value, Writeable, Enumerable, Configurable] |
| 632 // if args[1] is an accessor on args[0] | 632 // if args[1] is an accessor on args[0] |
| 633 // [true, GetFunction, SetFunction, Enumerable, Configurable] | 633 // [true, GetFunction, SetFunction, Enumerable, Configurable] |
| 634 static Object* Runtime_GetOwnProperty(Arguments args) { | 634 static Object* Runtime_GetOwnProperty(Arguments args) { |
| 635 ASSERT(args.length() == 2); | 635 ASSERT(args.length() == 2); |
| 636 HandleScope scope; | 636 HandleScope scope; |
| 637 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); | 637 Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); |
| 638 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); | 638 Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); |
| 639 LookupResult result; | 639 LookupResult result; |
| 640 CONVERT_CHECKED(JSObject, obj, args[0]); | 640 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
| 641 CONVERT_CHECKED(String, name, args[1]); | 641 CONVERT_ARG_CHECKED(String, name, 1); |
| 642 | 642 |
| 643 // This could be an element. | 643 // This could be an element. |
| 644 uint32_t index; | 644 uint32_t index; |
| 645 if (name->AsArrayIndex(&index)) { | 645 if (name->AsArrayIndex(&index)) { |
| 646 if (!obj->HasLocalElement(index)) { | 646 switch (obj->HasLocalElement(index)) { |
| 647 return Heap::undefined_value(); | 647 case JSObject::UNDEFINED_ELEMENT: |
| 648 } | 648 return Heap::undefined_value(); |
| 649 | 649 |
| 650 // Special handling of string objects according to ECMAScript 5 15.5.5.2. | 650 case JSObject::STRING_CHARACTER_ELEMENT: { |
| 651 // Note that this might be a string object with elements other than the | 651 // Special handling of string objects according to ECMAScript 5 |
| 652 // actual string value. This is covered by the subsequent cases. | 652 // 15.5.5.2. Note that this might be a string object with elements |
| 653 if (obj->IsStringObjectWithCharacterAt(index)) { | 653 // other than the actual string value. This is covered by the |
| 654 JSValue* js_value = JSValue::cast(obj); | 654 // subsequent cases. |
| 655 String* str = String::cast(js_value->value()); | 655 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); |
| 656 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 656 Handle<String> str(String::cast(js_value->value())); |
| 657 elms->set(VALUE_INDEX, str->SubString(index, index+1)); | 657 Handle<String> substr = SubString(str, index, index+1, NOT_TENURED); |
| 658 elms->set(WRITABLE_INDEX, Heap::false_value()); | |
| 659 elms->set(ENUMERABLE_INDEX, Heap::false_value()); | |
| 660 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); | |
| 661 return *desc; | |
| 662 } | |
| 663 | 658 |
| 664 // This can potentially be an element in the elements dictionary or | 659 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
| 665 // a fast element. | 660 elms->set(VALUE_INDEX, *substr); |
| 666 if (obj->HasDictionaryElements()) { | 661 elms->set(WRITABLE_INDEX, Heap::false_value()); |
| 667 NumberDictionary* dictionary = obj->element_dictionary(); | 662 elms->set(ENUMERABLE_INDEX, Heap::false_value()); |
| 668 int entry = dictionary->FindEntry(index); | 663 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); |
| 669 PropertyDetails details = dictionary->DetailsAt(entry); | 664 return *desc; |
| 670 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 665 } |
| 671 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); | 666 |
| 672 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); | 667 case JSObject::INTERCEPTED_ELEMENT: |
| 673 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); | 668 case JSObject::FAST_ELEMENT: { |
| 674 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); | 669 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
| 675 return *desc; | 670 Handle<Object> element = GetElement(Handle<Object>(obj), index); |
| 676 } else { | 671 elms->set(VALUE_INDEX, *element); |
| 677 // Elements that are stored as array elements always has: | 672 elms->set(WRITABLE_INDEX, Heap::true_value()); |
| 678 // writable: true, configurable: true, enumerable: true. | 673 elms->set(ENUMERABLE_INDEX, Heap::true_value()); |
| 679 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 674 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); |
| 680 elms->set(VALUE_INDEX, obj->GetElement(index)); | 675 return *desc; |
| 681 elms->set(WRITABLE_INDEX, Heap::true_value()); | 676 } |
| 682 elms->set(ENUMERABLE_INDEX, Heap::true_value()); | 677 |
| 683 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); | 678 case JSObject::DICTIONARY_ELEMENT: { |
| 684 return *desc; | 679 NumberDictionary* dictionary = obj->element_dictionary(); |
| 680 int entry = dictionary->FindEntry(index); |
| 681 ASSERT(entry != NumberDictionary::kNotFound); |
| 682 PropertyDetails details = dictionary->DetailsAt(entry); |
| 683 switch (details.type()) { |
| 684 case CALLBACKS: { |
| 685 // This is an accessor property with getter and/or setter. |
| 686 FixedArray* callbacks = |
| 687 FixedArray::cast(dictionary->ValueAt(entry)); |
| 688 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); |
| 689 elms->set(GETTER_INDEX, callbacks->get(0)); |
| 690 elms->set(SETTER_INDEX, callbacks->get(1)); |
| 691 break; |
| 692 } |
| 693 case NORMAL: |
| 694 // This is a data property. |
| 695 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
| 696 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); |
| 697 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); |
| 698 break; |
| 699 default: |
| 700 UNREACHABLE(); |
| 701 break; |
| 702 } |
| 703 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); |
| 704 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); |
| 705 return *desc; |
| 706 } |
| 685 } | 707 } |
| 686 } | 708 } |
| 687 | 709 |
| 688 // Use recursive implementation to also traverse hidden prototypes | 710 // Use recursive implementation to also traverse hidden prototypes |
| 689 GetOwnPropertyImplementation(obj, name, &result); | 711 GetOwnPropertyImplementation(*obj, *name, &result); |
| 690 | 712 |
| 691 if (!result.IsProperty()) { | 713 if (!result.IsProperty()) { |
| 692 return Heap::undefined_value(); | 714 return Heap::undefined_value(); |
| 693 } | 715 } |
| 694 if (result.type() == CALLBACKS) { | 716 if (result.type() == CALLBACKS) { |
| 695 Object* structure = result.GetCallbackObject(); | 717 Object* structure = result.GetCallbackObject(); |
| 696 if (structure->IsProxy() || structure->IsAccessorInfo()) { | 718 if (structure->IsProxy() || structure->IsAccessorInfo()) { |
| 697 // Property that is internally implemented as a callback or | 719 // Property that is internally implemented as a callback or |
| 698 // an API defined callback. | 720 // an API defined callback. |
| 699 Object* value = obj->GetPropertyWithCallback( | 721 Object* value = obj->GetPropertyWithCallback( |
| 700 obj, structure, name, result.holder()); | 722 *obj, structure, *name, result.holder()); |
| 723 if (value->IsFailure()) return value; |
| 701 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 724 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
| 702 elms->set(VALUE_INDEX, value); | 725 elms->set(VALUE_INDEX, value); |
| 703 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); | 726 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); |
| 704 } else if (structure->IsFixedArray()) { | 727 } else if (structure->IsFixedArray()) { |
| 705 // __defineGetter__/__defineSetter__ callback. | 728 // __defineGetter__/__defineSetter__ callback. |
| 706 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); | 729 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); |
| 707 elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0)); | 730 elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0)); |
| 708 elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1)); | 731 elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1)); |
| 709 } else { | 732 } else { |
| 710 return Heap::undefined_value(); | 733 return Heap::undefined_value(); |
| (...skipping 2611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3322 match = RegExpImpl::Exec(regexp, subject, index, regexp_info); | 3345 match = RegExpImpl::Exec(regexp, subject, index, regexp_info); |
| 3323 if (match.is_null()) { | 3346 if (match.is_null()) { |
| 3324 return Failure::Exception(); | 3347 return Failure::Exception(); |
| 3325 } | 3348 } |
| 3326 } while (!match->IsNull()); | 3349 } while (!match->IsNull()); |
| 3327 int matches = offsets.length() / 2; | 3350 int matches = offsets.length() / 2; |
| 3328 Handle<FixedArray> elements = Factory::NewFixedArray(matches); | 3351 Handle<FixedArray> elements = Factory::NewFixedArray(matches); |
| 3329 for (int i = 0; i < matches ; i++) { | 3352 for (int i = 0; i < matches ; i++) { |
| 3330 int from = offsets.at(i * 2); | 3353 int from = offsets.at(i * 2); |
| 3331 int to = offsets.at(i * 2 + 1); | 3354 int to = offsets.at(i * 2 + 1); |
| 3332 elements->set(i, *Factory::NewSubString(subject, from, to)); | 3355 Handle<String> match = Factory::NewSubString(subject, from, to); |
| 3356 elements->set(i, *match); |
| 3333 } | 3357 } |
| 3334 Handle<JSArray> result = Factory::NewJSArrayWithElements(elements); | 3358 Handle<JSArray> result = Factory::NewJSArrayWithElements(elements); |
| 3335 result->set_length(Smi::FromInt(matches)); | 3359 result->set_length(Smi::FromInt(matches)); |
| 3336 return *result; | 3360 return *result; |
| 3337 } | 3361 } |
| 3338 | 3362 |
| 3339 | 3363 |
| 3340 // Two smis before and after the match, for very long strings. | 3364 // Two smis before and after the match, for very long strings. |
| 3341 const int kMaxBuilderEntriesPerRegExpMatch = 5; | 3365 const int kMaxBuilderEntriesPerRegExpMatch = 5; |
| 3342 | 3366 |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3673 match_start); | 3697 match_start); |
| 3674 } | 3698 } |
| 3675 match_end = register_vector[1]; | 3699 match_end = register_vector[1]; |
| 3676 | 3700 |
| 3677 { | 3701 { |
| 3678 // Avoid accumulating new handles inside loop. | 3702 // Avoid accumulating new handles inside loop. |
| 3679 HandleScope temp_scope; | 3703 HandleScope temp_scope; |
| 3680 // Arguments array to replace function is match, captures, index and | 3704 // Arguments array to replace function is match, captures, index and |
| 3681 // subject, i.e., 3 + capture count in total. | 3705 // subject, i.e., 3 + capture count in total. |
| 3682 Handle<FixedArray> elements = Factory::NewFixedArray(3 + capture_count); | 3706 Handle<FixedArray> elements = Factory::NewFixedArray(3 + capture_count); |
| 3683 elements->set(0, *Factory::NewSubString(subject, | 3707 Handle<String> match = Factory::NewSubString(subject, |
| 3684 match_start, | 3708 match_start, |
| 3685 match_end)); | 3709 match_end); |
| 3710 elements->set(0, *match); |
| 3686 for (int i = 1; i <= capture_count; i++) { | 3711 for (int i = 1; i <= capture_count; i++) { |
| 3687 int start = register_vector[i * 2]; | 3712 int start = register_vector[i * 2]; |
| 3688 if (start >= 0) { | 3713 if (start >= 0) { |
| 3689 int end = register_vector[i * 2 + 1]; | 3714 int end = register_vector[i * 2 + 1]; |
| 3690 ASSERT(start <= end); | 3715 ASSERT(start <= end); |
| 3691 Handle<String> substring = Factory::NewSubString(subject, | 3716 Handle<String> substring = Factory::NewSubString(subject, |
| 3692 start, | 3717 start, |
| 3693 end); | 3718 end); |
| 3694 elements->set(i, *substring); | 3719 elements->set(i, *substring); |
| 3695 } else { | 3720 } else { |
| (...skipping 1843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5539 elements = Handle<FixedArray>(FixedArray::cast(obj)); | 5564 elements = Handle<FixedArray>(FixedArray::cast(obj)); |
| 5540 | 5565 |
| 5541 Vector<const char> chars = s->ToAsciiVector(); | 5566 Vector<const char> chars = s->ToAsciiVector(); |
| 5542 // Note, this will initialize all elements (not only the prefix) | 5567 // Note, this will initialize all elements (not only the prefix) |
| 5543 // to prevent GC from seeing partially initialized array. | 5568 // to prevent GC from seeing partially initialized array. |
| 5544 int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(), | 5569 int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(), |
| 5545 *elements, | 5570 *elements, |
| 5546 length); | 5571 length); |
| 5547 | 5572 |
| 5548 for (int i = num_copied_from_cache; i < length; ++i) { | 5573 for (int i = num_copied_from_cache; i < length; ++i) { |
| 5549 elements->set(i, *LookupSingleCharacterStringFromCode(chars[i])); | 5574 Handle<Object> str = LookupSingleCharacterStringFromCode(chars[i]); |
| 5575 elements->set(i, *str); |
| 5550 } | 5576 } |
| 5551 } else { | 5577 } else { |
| 5552 elements = Factory::NewFixedArray(length); | 5578 elements = Factory::NewFixedArray(length); |
| 5553 for (int i = 0; i < length; ++i) { | 5579 for (int i = 0; i < length; ++i) { |
| 5554 elements->set(i, *LookupSingleCharacterStringFromCode(s->Get(i))); | 5580 Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i)); |
| 5581 elements->set(i, *str); |
| 5555 } | 5582 } |
| 5556 } | 5583 } |
| 5557 | 5584 |
| 5558 #ifdef DEBUG | 5585 #ifdef DEBUG |
| 5559 for (int i = 0; i < length; ++i) { | 5586 for (int i = 0; i < length; ++i) { |
| 5560 ASSERT(String::cast(elements->get(i))->length() == 1); | 5587 ASSERT(String::cast(elements->get(i))->length() == 1); |
| 5561 } | 5588 } |
| 5562 #endif | 5589 #endif |
| 5563 | 5590 |
| 5564 return *Factory::NewJSArrayWithElements(elements); | 5591 return *Factory::NewJSArrayWithElements(elements); |
| (...skipping 2511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8076 // If estimated number of elements is more than half of length, a | 8103 // If estimated number of elements is more than half of length, a |
| 8077 // fixed array (fast case) is more time and space-efficient than a | 8104 // fixed array (fast case) is more time and space-efficient than a |
| 8078 // dictionary. | 8105 // dictionary. |
| 8079 bool fast_case = (estimate_nof_elements * 2) >= result_length; | 8106 bool fast_case = (estimate_nof_elements * 2) >= result_length; |
| 8080 | 8107 |
| 8081 Handle<FixedArray> storage; | 8108 Handle<FixedArray> storage; |
| 8082 if (fast_case) { | 8109 if (fast_case) { |
| 8083 // The backing storage array must have non-existing elements to | 8110 // The backing storage array must have non-existing elements to |
| 8084 // preserve holes across concat operations. | 8111 // preserve holes across concat operations. |
| 8085 storage = Factory::NewFixedArrayWithHoles(result_length); | 8112 storage = Factory::NewFixedArrayWithHoles(result_length); |
| 8086 result->set_map(*Factory::GetFastElementsMap(Handle<Map>(result->map()))); | 8113 Handle<Map> fast_map = |
| 8114 Factory::GetFastElementsMap(Handle<Map>(result->map())); |
| 8115 result->set_map(*fast_map); |
| 8087 } else { | 8116 } else { |
| 8088 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 8117 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
| 8089 uint32_t at_least_space_for = estimate_nof_elements + | 8118 uint32_t at_least_space_for = estimate_nof_elements + |
| 8090 (estimate_nof_elements >> 2); | 8119 (estimate_nof_elements >> 2); |
| 8091 storage = Handle<FixedArray>::cast( | 8120 storage = Handle<FixedArray>::cast( |
| 8092 Factory::NewNumberDictionary(at_least_space_for)); | 8121 Factory::NewNumberDictionary(at_least_space_for)); |
| 8093 result->set_map(*Factory::GetSlowElementsMap(Handle<Map>(result->map()))); | 8122 Handle<Map> slow_map = |
| 8123 Factory::GetSlowElementsMap(Handle<Map>(result->map())); |
| 8124 result->set_map(*slow_map); |
| 8094 } | 8125 } |
| 8095 | 8126 |
| 8096 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); | 8127 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); |
| 8097 | 8128 |
| 8098 ArrayConcatVisitor visitor(storage, result_length, fast_case); | 8129 ArrayConcatVisitor visitor(storage, result_length, fast_case); |
| 8099 | 8130 |
| 8100 IterateArguments(arguments, &visitor); | 8131 IterateArguments(arguments, &visitor); |
| 8101 | 8132 |
| 8102 result->set_length(*len); | 8133 result->set_length(*len); |
| 8103 // Please note the storage might have changed in the visitor. | 8134 // Please note the storage might have changed in the visitor. |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8400 if (obj->IsJSGlobalProxy()) { | 8431 if (obj->IsJSGlobalProxy()) { |
| 8401 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); | 8432 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype())); |
| 8402 } | 8433 } |
| 8403 | 8434 |
| 8404 | 8435 |
| 8405 // Check if the name is trivially convertible to an index and get the element | 8436 // Check if the name is trivially convertible to an index and get the element |
| 8406 // if so. | 8437 // if so. |
| 8407 uint32_t index; | 8438 uint32_t index; |
| 8408 if (name->AsArrayIndex(&index)) { | 8439 if (name->AsArrayIndex(&index)) { |
| 8409 Handle<FixedArray> details = Factory::NewFixedArray(2); | 8440 Handle<FixedArray> details = Factory::NewFixedArray(2); |
| 8410 details->set(0, Runtime::GetElementOrCharAt(obj, index)); | 8441 Object* element_or_char = Runtime::GetElementOrCharAt(obj, index); |
| 8442 details->set(0, element_or_char); |
| 8411 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 8443 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
| 8412 return *Factory::NewJSArrayWithElements(details); | 8444 return *Factory::NewJSArrayWithElements(details); |
| 8413 } | 8445 } |
| 8414 | 8446 |
| 8415 // Find the number of objects making up this. | 8447 // Find the number of objects making up this. |
| 8416 int length = LocalPrototypeChainLength(*obj); | 8448 int length = LocalPrototypeChainLength(*obj); |
| 8417 | 8449 |
| 8418 // Try local lookup on each of the objects. | 8450 // Try local lookup on each of the objects. |
| 8419 Handle<JSObject> jsproto = obj; | 8451 Handle<JSObject> jsproto = obj; |
| 8420 for (int i = 0; i < length; i++) { | 8452 for (int i = 0; i < length; i++) { |
| (...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9202 if (it.Done()) { | 9234 if (it.Done()) { |
| 9203 return Heap::undefined_value(); | 9235 return Heap::undefined_value(); |
| 9204 } | 9236 } |
| 9205 | 9237 |
| 9206 // Calculate the size of the result. | 9238 // Calculate the size of the result. |
| 9207 int details_size = kScopeDetailsSize; | 9239 int details_size = kScopeDetailsSize; |
| 9208 Handle<FixedArray> details = Factory::NewFixedArray(details_size); | 9240 Handle<FixedArray> details = Factory::NewFixedArray(details_size); |
| 9209 | 9241 |
| 9210 // Fill in scope details. | 9242 // Fill in scope details. |
| 9211 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); | 9243 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); |
| 9212 details->set(kScopeDetailsObjectIndex, *it.ScopeObject()); | 9244 Handle<JSObject> scope_object = it.ScopeObject(); |
| 9245 details->set(kScopeDetailsObjectIndex, *scope_object); |
| 9213 | 9246 |
| 9214 return *Factory::NewJSArrayWithElements(details); | 9247 return *Factory::NewJSArrayWithElements(details); |
| 9215 } | 9248 } |
| 9216 | 9249 |
| 9217 | 9250 |
| 9218 static Object* Runtime_DebugPrintScopes(Arguments args) { | 9251 static Object* Runtime_DebugPrintScopes(Arguments args) { |
| 9219 HandleScope scope; | 9252 HandleScope scope; |
| 9220 ASSERT(args.length() == 0); | 9253 ASSERT(args.length() == 0); |
| 9221 | 9254 |
| 9222 #ifdef DEBUG | 9255 #ifdef DEBUG |
| (...skipping 24 matching lines...) Expand all Loading... |
| 9247 int frames_count = OS::StackWalk(frames); | 9280 int frames_count = OS::StackWalk(frames); |
| 9248 if (frames_count == OS::kStackWalkError) { | 9281 if (frames_count == OS::kStackWalkError) { |
| 9249 return Heap::undefined_value(); | 9282 return Heap::undefined_value(); |
| 9250 } | 9283 } |
| 9251 | 9284 |
| 9252 Handle<String> address_str = Factory::LookupAsciiSymbol("address"); | 9285 Handle<String> address_str = Factory::LookupAsciiSymbol("address"); |
| 9253 Handle<String> text_str = Factory::LookupAsciiSymbol("text"); | 9286 Handle<String> text_str = Factory::LookupAsciiSymbol("text"); |
| 9254 Handle<FixedArray> frames_array = Factory::NewFixedArray(frames_count); | 9287 Handle<FixedArray> frames_array = Factory::NewFixedArray(frames_count); |
| 9255 for (int i = 0; i < frames_count; i++) { | 9288 for (int i = 0; i < frames_count; i++) { |
| 9256 Handle<JSObject> frame_value = Factory::NewJSObject(Top::object_function()); | 9289 Handle<JSObject> frame_value = Factory::NewJSObject(Top::object_function()); |
| 9257 frame_value->SetProperty( | 9290 Handle<Object> frame_address = |
| 9258 *address_str, | 9291 Factory::NewNumberFromInt(reinterpret_cast<int>(frames[i].address)); |
| 9259 *Factory::NewNumberFromInt(reinterpret_cast<int>(frames[i].address)), | 9292 |
| 9260 NONE); | 9293 frame_value->SetProperty(*address_str, *frame_address, NONE); |
| 9261 | 9294 |
| 9262 // Get the stack walk text for this frame. | 9295 // Get the stack walk text for this frame. |
| 9263 Handle<String> frame_text; | 9296 Handle<String> frame_text; |
| 9264 int frame_text_length = StrLength(frames[i].text); | 9297 int frame_text_length = StrLength(frames[i].text); |
| 9265 if (frame_text_length > 0) { | 9298 if (frame_text_length > 0) { |
| 9266 Vector<const char> str(frames[i].text, frame_text_length); | 9299 Vector<const char> str(frames[i].text, frame_text_length); |
| 9267 frame_text = Factory::NewStringFromAscii(str); | 9300 frame_text = Factory::NewStringFromAscii(str); |
| 9268 } | 9301 } |
| 9269 | 9302 |
| 9270 if (!frame_text.is_null()) { | 9303 if (!frame_text.is_null()) { |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9597 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, | 9630 static Handle<Context> CopyWithContextChain(Handle<Context> context_chain, |
| 9598 Handle<Context> function_context) { | 9631 Handle<Context> function_context) { |
| 9599 // At the bottom of the chain. Return the function context to link to. | 9632 // At the bottom of the chain. Return the function context to link to. |
| 9600 if (context_chain->is_function_context()) { | 9633 if (context_chain->is_function_context()) { |
| 9601 return function_context; | 9634 return function_context; |
| 9602 } | 9635 } |
| 9603 | 9636 |
| 9604 // Recursively copy the with contexts. | 9637 // Recursively copy the with contexts. |
| 9605 Handle<Context> previous(context_chain->previous()); | 9638 Handle<Context> previous(context_chain->previous()); |
| 9606 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); | 9639 Handle<JSObject> extension(JSObject::cast(context_chain->extension())); |
| 9607 return Factory::NewWithContext( | 9640 Handle<Context> context = CopyWithContextChain(function_context, previous); |
| 9608 CopyWithContextChain(function_context, previous), | 9641 return Factory::NewWithContext(context, |
| 9609 extension, | 9642 extension, |
| 9610 context_chain->IsCatchContext()); | 9643 context_chain->IsCatchContext()); |
| 9611 } | 9644 } |
| 9612 | 9645 |
| 9613 | 9646 |
| 9614 // Helper function to find or create the arguments object for | 9647 // Helper function to find or create the arguments object for |
| 9615 // Runtime_DebugEvaluate. | 9648 // Runtime_DebugEvaluate. |
| 9616 static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame, | 9649 static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame, |
| 9617 Handle<JSFunction> function, | 9650 Handle<JSFunction> function, |
| 9618 Handle<SerializedScopeInfo> scope_info, | 9651 Handle<SerializedScopeInfo> scope_info, |
| 9619 const ScopeInfo<>* sinfo, | 9652 const ScopeInfo<>* sinfo, |
| 9620 Handle<Context> function_context) { | 9653 Handle<Context> function_context) { |
| (...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10708 } else { | 10741 } else { |
| 10709 // Handle last resort GC and make sure to allow future allocations | 10742 // Handle last resort GC and make sure to allow future allocations |
| 10710 // to grow the heap without causing GCs (if possible). | 10743 // to grow the heap without causing GCs (if possible). |
| 10711 Counters::gc_last_resort_from_js.Increment(); | 10744 Counters::gc_last_resort_from_js.Increment(); |
| 10712 Heap::CollectAllGarbage(false); | 10745 Heap::CollectAllGarbage(false); |
| 10713 } | 10746 } |
| 10714 } | 10747 } |
| 10715 | 10748 |
| 10716 | 10749 |
| 10717 } } // namespace v8::internal | 10750 } } // namespace v8::internal |
| OLD | NEW |