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 5737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5748 Handle<FixedArray> details = Factory::NewFixedArray(2); | 5748 Handle<FixedArray> details = Factory::NewFixedArray(2); |
5749 details->set(0, Runtime::GetElementOrCharAt(obj, index)); | 5749 details->set(0, Runtime::GetElementOrCharAt(obj, index)); |
5750 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 5750 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
5751 return *Factory::NewJSArrayWithElements(details); | 5751 return *Factory::NewJSArrayWithElements(details); |
5752 } | 5752 } |
5753 | 5753 |
5754 // Find the number of objects making up this. | 5754 // Find the number of objects making up this. |
5755 int length = LocalPrototypeChainLength(*obj); | 5755 int length = LocalPrototypeChainLength(*obj); |
5756 | 5756 |
5757 // Try local lookup on each of the objects. | 5757 // Try local lookup on each of the objects. |
5758 LookupResult result; | |
5759 Handle<JSObject> jsproto = obj; | 5758 Handle<JSObject> jsproto = obj; |
5760 for (int i = 0; i < length; i++) { | 5759 for (int i = 0; i < length; i++) { |
| 5760 LookupResult result; |
5761 jsproto->LocalLookup(*name, &result); | 5761 jsproto->LocalLookup(*name, &result); |
5762 if (result.IsProperty()) { | 5762 if (result.IsProperty()) { |
5763 break; | 5763 // LookupResult is not GC safe as it holds raw object pointers. |
| 5764 // GC can happen later in this code so put the required fields into |
| 5765 // local variables using handles when required for later use. |
| 5766 PropertyType result_type = result.type(); |
| 5767 Handle<Object> result_callback_obj; |
| 5768 if (result_type == CALLBACKS) { |
| 5769 result_callback_obj = Handle<Object>(result.GetCallbackObject()); |
| 5770 } |
| 5771 Smi* property_details = result.GetPropertyDetails().AsSmi(); |
| 5772 // DebugLookupResultValue can cause GC so details from LookupResult needs |
| 5773 // to be copied to handles before this. |
| 5774 bool caught_exception = false; |
| 5775 Object* raw_value = DebugLookupResultValue(*obj, *name, &result, |
| 5776 &caught_exception); |
| 5777 if (raw_value->IsFailure()) return raw_value; |
| 5778 Handle<Object> value(raw_value); |
| 5779 |
| 5780 // If the callback object is a fixed array then it contains JavaScript |
| 5781 // getter and/or setter. |
| 5782 bool hasJavaScriptAccessors = result_type == CALLBACKS && |
| 5783 result_callback_obj->IsFixedArray(); |
| 5784 Handle<FixedArray> details = |
| 5785 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
| 5786 details->set(0, *value); |
| 5787 details->set(1, property_details); |
| 5788 if (hasJavaScriptAccessors) { |
| 5789 details->set(2, |
| 5790 caught_exception ? Heap::true_value() |
| 5791 : Heap::false_value()); |
| 5792 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); |
| 5793 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); |
| 5794 } |
| 5795 |
| 5796 return *Factory::NewJSArrayWithElements(details); |
5764 } | 5797 } |
5765 if (i < length - 1) { | 5798 if (i < length - 1) { |
5766 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5799 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
5767 } | 5800 } |
5768 } | 5801 } |
5769 | 5802 |
5770 if (result.IsProperty()) { | |
5771 // LookupResult is not GC safe as all its members are raw object pointers. | |
5772 // When calling DebugLookupResultValue GC can happen as this might invoke | |
5773 // callbacks. After the call to DebugLookupResultValue the callback object | |
5774 // in the LookupResult might still be needed. Put it into a handle for later | |
5775 // use. | |
5776 PropertyType result_type = result.type(); | |
5777 Handle<Object> result_callback_obj; | |
5778 if (result_type == CALLBACKS) { | |
5779 result_callback_obj = Handle<Object>(result.GetCallbackObject()); | |
5780 } | |
5781 | |
5782 // Find the actual value. Don't use result after this call as it's content | |
5783 // can be invalid. | |
5784 bool caught_exception = false; | |
5785 Object* value = DebugLookupResultValue(*obj, *name, &result, | |
5786 &caught_exception); | |
5787 if (value->IsFailure()) return value; | |
5788 Handle<Object> value_handle(value); | |
5789 | |
5790 // If the callback object is a fixed array then it contains JavaScript | |
5791 // getter and/or setter. | |
5792 bool hasJavaScriptAccessors = result_type == CALLBACKS && | |
5793 result_callback_obj->IsFixedArray(); | |
5794 Handle<FixedArray> details = | |
5795 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | |
5796 details->set(0, *value_handle); | |
5797 details->set(1, result.GetPropertyDetails().AsSmi()); | |
5798 if (hasJavaScriptAccessors) { | |
5799 details->set(2, | |
5800 caught_exception ? Heap::true_value() : Heap::false_value()); | |
5801 details->set(3, FixedArray::cast(result.GetCallbackObject())->get(0)); | |
5802 details->set(4, FixedArray::cast(result.GetCallbackObject())->get(1)); | |
5803 } | |
5804 | |
5805 return *Factory::NewJSArrayWithElements(details); | |
5806 } | |
5807 return Heap::undefined_value(); | 5803 return Heap::undefined_value(); |
5808 } | 5804 } |
5809 | 5805 |
5810 | 5806 |
5811 static Object* Runtime_DebugGetProperty(Arguments args) { | 5807 static Object* Runtime_DebugGetProperty(Arguments args) { |
5812 HandleScope scope; | 5808 HandleScope scope; |
5813 | 5809 |
5814 ASSERT(args.length() == 2); | 5810 ASSERT(args.length() == 2); |
5815 | 5811 |
5816 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 5812 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
(...skipping 1909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7726 } else { | 7722 } else { |
7727 // Handle last resort GC and make sure to allow future allocations | 7723 // Handle last resort GC and make sure to allow future allocations |
7728 // to grow the heap without causing GCs (if possible). | 7724 // to grow the heap without causing GCs (if possible). |
7729 Counters::gc_last_resort_from_js.Increment(); | 7725 Counters::gc_last_resort_from_js.Increment(); |
7730 Heap::CollectAllGarbage(false); | 7726 Heap::CollectAllGarbage(false); |
7731 } | 7727 } |
7732 } | 7728 } |
7733 | 7729 |
7734 | 7730 |
7735 } } // namespace v8::internal | 7731 } } // namespace v8::internal |
OLD | NEW |