OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 10824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10835 | 10835 |
10836 | 10836 |
10837 RUNTIME_FUNCTION(Runtime_Break) { | 10837 RUNTIME_FUNCTION(Runtime_Break) { |
10838 SealHandleScope shs(isolate); | 10838 SealHandleScope shs(isolate); |
10839 DCHECK(args.length() == 0); | 10839 DCHECK(args.length() == 0); |
10840 isolate->stack_guard()->RequestDebugBreak(); | 10840 isolate->stack_guard()->RequestDebugBreak(); |
10841 return isolate->heap()->undefined_value(); | 10841 return isolate->heap()->undefined_value(); |
10842 } | 10842 } |
10843 | 10843 |
10844 | 10844 |
10845 static Handle<Object> DebugLookupResultValue(Isolate* isolate, | 10845 static Handle<Object> DebugLookupResultValue(LookupIterator* it, |
10846 Handle<Object> receiver, | |
10847 Handle<Name> name, | |
10848 LookupResult* result, | |
10849 bool* has_caught = NULL) { | 10846 bool* has_caught = NULL) { |
10850 Handle<Object> value = isolate->factory()->undefined_value(); | 10847 for (; it->IsFound(); it->Next()) { |
10851 if (!result->IsFound()) return value; | 10848 switch (it->state()) { |
10852 switch (result->type()) { | 10849 case LookupIterator::NOT_FOUND: |
10853 case NORMAL: | 10850 UNREACHABLE(); |
10854 return JSObject::GetNormalizedProperty(handle(result->holder(), isolate), | 10851 case LookupIterator::ACCESS_CHECK: |
10855 result); | 10852 // Ignore access checks. |
10856 case FIELD: | 10853 break; |
10857 return JSObject::FastPropertyAt(handle(result->holder(), isolate), | 10854 case LookupIterator::INTERCEPTOR: |
10858 result->representation(), | 10855 case LookupIterator::JSPROXY: |
10859 result->GetFieldIndex()); | 10856 return it->isolate()->factory()->undefined_value(); |
10860 case CONSTANT: | 10857 case LookupIterator::PROPERTY: |
10861 return handle(result->GetConstant(), isolate); | 10858 if (!it->HasProperty()) continue; |
10862 case CALLBACKS: { | 10859 switch (it->property_kind()) { |
10863 Handle<Object> structure(result->GetCallbackObject(), isolate); | 10860 case LookupIterator::ACCESSOR: { |
10864 DCHECK(!structure->IsForeign()); | 10861 Handle<Object> accessors = it->GetAccessors(); |
10865 if (structure->IsAccessorInfo()) { | 10862 if (!accessors->IsAccessorInfo()) { |
10866 MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor( | 10863 return it->isolate()->factory()->undefined_value(); |
10867 receiver, name, handle(result->holder(), isolate), structure); | 10864 } |
10868 if (!obj.ToHandle(&value)) { | 10865 MaybeHandle<Object> maybe_result = |
10869 value = handle(isolate->pending_exception(), isolate); | 10866 JSObject::GetPropertyWithAccessor(it->GetReceiver(), it->name(), |
10870 isolate->clear_pending_exception(); | 10867 it->GetHolder<JSObject>(), |
10871 if (has_caught != NULL) *has_caught = true; | 10868 accessors); |
10872 return value; | 10869 Handle<Object> result; |
| 10870 if (!maybe_result.ToHandle(&result)) { |
| 10871 result = |
| 10872 handle(it->isolate()->pending_exception(), it->isolate()); |
| 10873 it->isolate()->clear_pending_exception(); |
| 10874 if (has_caught != NULL) *has_caught = true; |
| 10875 } |
| 10876 return result; |
| 10877 } |
| 10878 case LookupIterator::DATA: |
| 10879 return it->GetDataValue(); |
10873 } | 10880 } |
10874 } | |
10875 break; | |
10876 } | 10881 } |
10877 case INTERCEPTOR: | |
10878 case HANDLER: | |
10879 break; | |
10880 case NONEXISTENT: | |
10881 UNREACHABLE(); | |
10882 break; | |
10883 } | 10882 } |
10884 return value; | 10883 |
| 10884 return it->isolate()->factory()->undefined_value(); |
10885 } | 10885 } |
10886 | 10886 |
10887 | 10887 |
10888 // Get debugger related details for an object property. | 10888 // Get debugger related details for an object property, in the following format: |
10889 // args[0]: object holding property | |
10890 // args[1]: name of the property | |
10891 // | |
10892 // The array returned contains the following information: | |
10893 // 0: Property value | 10889 // 0: Property value |
10894 // 1: Property details | 10890 // 1: Property details |
10895 // 2: Property value is exception | 10891 // 2: Property value is exception |
10896 // 3: Getter function if defined | 10892 // 3: Getter function if defined |
10897 // 4: Setter function if defined | 10893 // 4: Setter function if defined |
10898 // Items 2-4 are only filled if the property has either a getter or a setter | 10894 // Items 2-4 are only filled if the property has either a getter or a setter. |
10899 // defined through __defineGetter__ and/or __defineSetter__. | |
10900 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) { | 10895 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) { |
10901 HandleScope scope(isolate); | 10896 HandleScope scope(isolate); |
10902 | 10897 |
10903 DCHECK(args.length() == 2); | 10898 DCHECK(args.length() == 2); |
10904 | 10899 |
10905 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 10900 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
10906 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); | 10901 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
10907 | 10902 |
10908 // Make sure to set the current context to the context before the debugger was | 10903 // Make sure to set the current context to the context before the debugger was |
10909 // entered (if the debugger is entered). The reason for switching context here | 10904 // entered (if the debugger is entered). The reason for switching context here |
(...skipping 14 matching lines...) Expand all Loading... |
10924 Handle<Object> element_or_char; | 10919 Handle<Object> element_or_char; |
10925 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 10920 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
10926 isolate, element_or_char, | 10921 isolate, element_or_char, |
10927 Runtime::GetElementOrCharAt(isolate, obj, index)); | 10922 Runtime::GetElementOrCharAt(isolate, obj, index)); |
10928 details->set(0, *element_or_char); | 10923 details->set(0, *element_or_char); |
10929 details->set( | 10924 details->set( |
10930 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); | 10925 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); |
10931 return *isolate->factory()->NewJSArrayWithElements(details); | 10926 return *isolate->factory()->NewJSArrayWithElements(details); |
10932 } | 10927 } |
10933 | 10928 |
10934 // Find the number of objects making up this. | 10929 LookupIterator it(obj, name, LookupIterator::CHECK_HIDDEN); |
10935 int length = OwnPrototypeChainLength(*obj); | 10930 bool has_caught = false; |
| 10931 Handle<Object> value = DebugLookupResultValue(&it, &has_caught); |
| 10932 if (!it.IsFound()) return isolate->heap()->undefined_value(); |
10936 | 10933 |
10937 // Try own lookup on each of the objects. | 10934 Handle<Object> maybe_pair; |
10938 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | 10935 if (it.state() == LookupIterator::PROPERTY && |
10939 for (int i = 0; i < length; i++) { | 10936 it.property_kind() == LookupIterator::ACCESSOR) { |
10940 DCHECK(!iter.IsAtEnd()); | 10937 maybe_pair = it.GetAccessors(); |
10941 Handle<JSObject> jsproto = | |
10942 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
10943 LookupResult result(isolate); | |
10944 jsproto->LookupOwn(name, &result); | |
10945 if (result.IsFound()) { | |
10946 // LookupResult is not GC safe as it holds raw object pointers. | |
10947 // GC can happen later in this code so put the required fields into | |
10948 // local variables using handles when required for later use. | |
10949 Handle<Object> result_callback_obj; | |
10950 if (result.IsPropertyCallbacks()) { | |
10951 result_callback_obj = Handle<Object>(result.GetCallbackObject(), | |
10952 isolate); | |
10953 } | |
10954 | |
10955 | |
10956 bool has_caught = false; | |
10957 Handle<Object> value = DebugLookupResultValue( | |
10958 isolate, obj, name, &result, &has_caught); | |
10959 | |
10960 // If the callback object is a fixed array then it contains JavaScript | |
10961 // getter and/or setter. | |
10962 bool has_js_accessors = result.IsPropertyCallbacks() && | |
10963 result_callback_obj->IsAccessorPair(); | |
10964 Handle<FixedArray> details = | |
10965 isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2); | |
10966 details->set(0, *value); | |
10967 details->set(1, result.GetPropertyDetails().AsSmi()); | |
10968 if (has_js_accessors) { | |
10969 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); | |
10970 details->set(2, isolate->heap()->ToBoolean(has_caught)); | |
10971 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); | |
10972 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); | |
10973 } | |
10974 | |
10975 return *isolate->factory()->NewJSArrayWithElements(details); | |
10976 } | |
10977 iter.Advance(); | |
10978 } | 10938 } |
10979 | 10939 |
10980 return isolate->heap()->undefined_value(); | 10940 // If the callback object is a fixed array then it contains JavaScript |
| 10941 // getter and/or setter. |
| 10942 bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair(); |
| 10943 Handle<FixedArray> details = |
| 10944 isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2); |
| 10945 details->set(0, *value); |
| 10946 // TODO(verwaest): Get rid of this random way of handling interceptors. |
| 10947 PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR |
| 10948 ? PropertyDetails(NONE, INTERCEPTOR, 0) |
| 10949 : it.property_details(); |
| 10950 details->set(1, d.AsSmi()); |
| 10951 if (has_js_accessors) { |
| 10952 AccessorPair* accessors = AccessorPair::cast(*maybe_pair); |
| 10953 details->set(2, isolate->heap()->ToBoolean(has_caught)); |
| 10954 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); |
| 10955 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); |
| 10956 } |
| 10957 |
| 10958 return *isolate->factory()->NewJSArrayWithElements(details); |
10981 } | 10959 } |
10982 | 10960 |
10983 | 10961 |
10984 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { | 10962 RUNTIME_FUNCTION(Runtime_DebugGetProperty) { |
10985 HandleScope scope(isolate); | 10963 HandleScope scope(isolate); |
10986 | 10964 |
10987 DCHECK(args.length() == 2); | 10965 DCHECK(args.length() == 2); |
10988 | 10966 |
10989 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 10967 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
10990 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); | 10968 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
10991 | 10969 |
10992 LookupResult result(isolate); | 10970 LookupIterator it(obj, name, LookupIterator::CHECK_DERIVED); |
10993 obj->Lookup(name, &result); | 10971 return *DebugLookupResultValue(&it); |
10994 return *DebugLookupResultValue(isolate, obj, name, &result); | |
10995 } | 10972 } |
10996 | 10973 |
10997 | 10974 |
10998 // Return the property type calculated from the property details. | 10975 // Return the property type calculated from the property details. |
10999 // args[0]: smi with property details. | 10976 // args[0]: smi with property details. |
11000 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) { | 10977 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) { |
11001 SealHandleScope shs(isolate); | 10978 SealHandleScope shs(isolate); |
11002 DCHECK(args.length() == 1); | 10979 DCHECK(args.length() == 1); |
11003 CONVERT_PROPERTY_DETAILS_CHECKED(details, 0); | 10980 CONVERT_PROPERTY_DETAILS_CHECKED(details, 0); |
11004 return Smi::FromInt(static_cast<int>(details.type())); | 10981 return Smi::FromInt(static_cast<int>(details.type())); |
(...skipping 4617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15622 } | 15599 } |
15623 return NULL; | 15600 return NULL; |
15624 } | 15601 } |
15625 | 15602 |
15626 | 15603 |
15627 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15604 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15628 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15605 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15629 } | 15606 } |
15630 | 15607 |
15631 } } // namespace v8::internal | 15608 } } // namespace v8::internal |
OLD | NEW |