| 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 |