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 16 matching lines...) Expand all Loading... | |
27 #include "src/full-codegen.h" | 27 #include "src/full-codegen.h" |
28 #include "src/global-handles.h" | 28 #include "src/global-handles.h" |
29 #include "src/isolate-inl.h" | 29 #include "src/isolate-inl.h" |
30 #include "src/json-parser.h" | 30 #include "src/json-parser.h" |
31 #include "src/json-stringifier.h" | 31 #include "src/json-stringifier.h" |
32 #include "src/jsregexp-inl.h" | 32 #include "src/jsregexp-inl.h" |
33 #include "src/jsregexp.h" | 33 #include "src/jsregexp.h" |
34 #include "src/liveedit.h" | 34 #include "src/liveedit.h" |
35 #include "src/misc-intrinsics.h" | 35 #include "src/misc-intrinsics.h" |
36 #include "src/parser.h" | 36 #include "src/parser.h" |
37 #include "src/prototype.h" | |
37 #include "src/runtime.h" | 38 #include "src/runtime.h" |
38 #include "src/runtime-profiler.h" | 39 #include "src/runtime-profiler.h" |
39 #include "src/scopeinfo.h" | 40 #include "src/scopeinfo.h" |
40 #include "src/smart-pointers.h" | 41 #include "src/smart-pointers.h" |
41 #include "src/string-search.h" | 42 #include "src/string-search.h" |
42 #include "src/stub-cache.h" | 43 #include "src/stub-cache.h" |
43 #include "src/uri.h" | 44 #include "src/uri.h" |
44 #include "src/v8threads.h" | 45 #include "src/v8threads.h" |
45 #include "src/vm-state-inl.h" | 46 #include "src/vm-state-inl.h" |
46 | 47 |
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1801 return JSObject::cast(obj)->class_name(); | 1802 return JSObject::cast(obj)->class_name(); |
1802 } | 1803 } |
1803 | 1804 |
1804 | 1805 |
1805 RUNTIME_FUNCTION(Runtime_GetPrototype) { | 1806 RUNTIME_FUNCTION(Runtime_GetPrototype) { |
1806 HandleScope scope(isolate); | 1807 HandleScope scope(isolate); |
1807 ASSERT(args.length() == 1); | 1808 ASSERT(args.length() == 1); |
1808 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); | 1809 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |
1809 // We don't expect access checks to be needed on JSProxy objects. | 1810 // We don't expect access checks to be needed on JSProxy objects. |
1810 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 1811 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
1812 PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | |
1811 do { | 1813 do { |
1812 if (obj->IsAccessCheckNeeded() && | 1814 if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && |
1813 !isolate->MayNamedAccess(Handle<JSObject>::cast(obj), | 1815 !isolate->MayNamedAccess( |
1814 isolate->factory()->proto_string(), | 1816 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), |
1815 v8::ACCESS_GET)) { | 1817 isolate->factory()->proto_string(), v8::ACCESS_GET)) { |
1816 isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj), | 1818 isolate->ReportFailedAccessCheck( |
1817 v8::ACCESS_GET); | 1819 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), |
1820 v8::ACCESS_GET); | |
1818 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 1821 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
1819 return isolate->heap()->undefined_value(); | 1822 return isolate->heap()->undefined_value(); |
1820 } | 1823 } |
1821 obj = Object::GetPrototype(isolate, obj); | 1824 iter.Advance(); |
1822 } while (obj->IsJSObject() && | 1825 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
1823 JSObject::cast(*obj)->map()->is_hidden_prototype()); | 1826 return *PrototypeIterator::GetCurrent(iter); |
1824 return *obj; | 1827 } |
1828 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); | |
1829 return *PrototypeIterator::GetCurrent(iter); | |
1825 } | 1830 } |
1826 | 1831 |
1827 | 1832 |
1828 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes( | 1833 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes( |
1829 Isolate* isolate, Handle<Object> receiver) { | 1834 Isolate* isolate, Handle<Object> receiver) { |
1830 Handle<Object> current = Object::GetPrototype(isolate, receiver); | 1835 PrototypeIterator iter(isolate, receiver); |
1831 while (current->IsJSObject() && | 1836 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { |
1832 JSObject::cast(*current)->map()->is_hidden_prototype()) { | 1837 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { |
1833 current = Object::GetPrototype(isolate, current); | 1838 return PrototypeIterator::GetCurrent(iter); |
1839 } | |
1840 iter.Advance(); | |
1834 } | 1841 } |
1835 return current; | 1842 return PrototypeIterator::GetCurrent(iter); |
1836 } | 1843 } |
1837 | 1844 |
1838 | 1845 |
1839 RUNTIME_FUNCTION(Runtime_SetPrototype) { | 1846 RUNTIME_FUNCTION(Runtime_SetPrototype) { |
1840 HandleScope scope(isolate); | 1847 HandleScope scope(isolate); |
1841 ASSERT(args.length() == 2); | 1848 ASSERT(args.length() == 2); |
1842 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 1849 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
1843 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); | 1850 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); |
1844 if (obj->IsAccessCheckNeeded() && | 1851 if (obj->IsAccessCheckNeeded() && |
1845 !isolate->MayNamedAccess( | 1852 !isolate->MayNamedAccess( |
(...skipping 24 matching lines...) Expand all Loading... | |
1870 return *result; | 1877 return *result; |
1871 } | 1878 } |
1872 | 1879 |
1873 | 1880 |
1874 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) { | 1881 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) { |
1875 HandleScope shs(isolate); | 1882 HandleScope shs(isolate); |
1876 ASSERT(args.length() == 2); | 1883 ASSERT(args.length() == 2); |
1877 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). | 1884 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). |
1878 CONVERT_ARG_HANDLE_CHECKED(Object, O, 0); | 1885 CONVERT_ARG_HANDLE_CHECKED(Object, O, 0); |
1879 CONVERT_ARG_HANDLE_CHECKED(Object, V, 1); | 1886 CONVERT_ARG_HANDLE_CHECKED(Object, V, 1); |
1887 PrototypeIterator iter(isolate, V); | |
1880 while (true) { | 1888 while (true) { |
1881 Handle<Object> prototype = Object::GetPrototype(isolate, V); | 1889 if (iter.IsAtEnd()) return isolate->heap()->false_value(); |
1882 if (prototype->IsNull()) return isolate->heap()->false_value(); | 1890 if (iter.IsAtEnd(O)) return isolate->heap()->true_value(); |
1883 if (*O == *prototype) return isolate->heap()->true_value(); | 1891 iter.Advance(); |
1884 V = prototype; | |
1885 } | 1892 } |
1886 } | 1893 } |
1887 | 1894 |
1888 | 1895 |
1889 // Enumerator used as indices into the array returned from GetOwnProperty | 1896 // Enumerator used as indices into the array returned from GetOwnProperty |
1890 enum PropertyDescriptorIndices { | 1897 enum PropertyDescriptorIndices { |
1891 IS_ACCESSOR_INDEX, | 1898 IS_ACCESSOR_INDEX, |
1892 VALUE_INDEX, | 1899 VALUE_INDEX, |
1893 GETTER_INDEX, | 1900 GETTER_INDEX, |
1894 SETTER_INDEX, | 1901 SETTER_INDEX, |
(...skipping 2901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4796 // Handle [] indexing on String objects | 4803 // Handle [] indexing on String objects |
4797 if (object->IsStringObjectWithCharacterAt(index)) { | 4804 if (object->IsStringObjectWithCharacterAt(index)) { |
4798 Handle<JSValue> js_value = Handle<JSValue>::cast(object); | 4805 Handle<JSValue> js_value = Handle<JSValue>::cast(object); |
4799 Handle<Object> result = | 4806 Handle<Object> result = |
4800 GetCharAt(Handle<String>(String::cast(js_value->value())), index); | 4807 GetCharAt(Handle<String>(String::cast(js_value->value())), index); |
4801 if (!result->IsUndefined()) return result; | 4808 if (!result->IsUndefined()) return result; |
4802 } | 4809 } |
4803 | 4810 |
4804 Handle<Object> result; | 4811 Handle<Object> result; |
4805 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { | 4812 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
4806 Handle<Object> proto(object->GetPrototype(isolate), isolate); | 4813 PrototypeIterator iter(isolate, object); |
4807 return Object::GetElement(isolate, proto, index); | 4814 return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter), |
4815 index); | |
4808 } else { | 4816 } else { |
4809 return Object::GetElement(isolate, object, index); | 4817 return Object::GetElement(isolate, object, index); |
4810 } | 4818 } |
4811 } | 4819 } |
4812 | 4820 |
4813 | 4821 |
4814 MUST_USE_RESULT | 4822 MUST_USE_RESULT |
4815 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) { | 4823 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) { |
4816 if (key->IsName()) { | 4824 if (key->IsName()) { |
4817 return Handle<Name>::cast(key); | 4825 return Handle<Name>::cast(key); |
(...skipping 5860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10678 // or undefined) or a number representing the positive length of an interval | 10686 // or undefined) or a number representing the positive length of an interval |
10679 // starting at index 0. | 10687 // starting at index 0. |
10680 // Intervals can span over some keys that are not in the object. | 10688 // Intervals can span over some keys that are not in the object. |
10681 RUNTIME_FUNCTION(Runtime_GetArrayKeys) { | 10689 RUNTIME_FUNCTION(Runtime_GetArrayKeys) { |
10682 HandleScope scope(isolate); | 10690 HandleScope scope(isolate); |
10683 ASSERT(args.length() == 2); | 10691 ASSERT(args.length() == 2); |
10684 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); | 10692 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); |
10685 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 10693 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
10686 if (array->elements()->IsDictionary()) { | 10694 if (array->elements()->IsDictionary()) { |
10687 Handle<FixedArray> keys = isolate->factory()->empty_fixed_array(); | 10695 Handle<FixedArray> keys = isolate->factory()->empty_fixed_array(); |
10688 for (Handle<Object> p = array; | 10696 for (PrototypeIterator iter(isolate, array, |
10689 !p->IsNull(); | 10697 PrototypeIterator::START_AT_RECEIVER); |
10690 p = Handle<Object>(p->GetPrototype(isolate), isolate)) { | 10698 !iter.IsAtEnd(); iter.Advance()) { |
10691 if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) { | 10699 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() || |
10700 JSObject::cast(*PrototypeIterator::GetCurrent(iter)) | |
10701 ->HasIndexedInterceptor()) { | |
10692 // Bail out if we find a proxy or interceptor, likely not worth | 10702 // Bail out if we find a proxy or interceptor, likely not worth |
10693 // collecting keys in that case. | 10703 // collecting keys in that case. |
10694 return *isolate->factory()->NewNumberFromUint(length); | 10704 return *isolate->factory()->NewNumberFromUint(length); |
10695 } | 10705 } |
10696 Handle<JSObject> current = Handle<JSObject>::cast(p); | 10706 Handle<JSObject> current = |
10707 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
10697 Handle<FixedArray> current_keys = | 10708 Handle<FixedArray> current_keys = |
10698 isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE)); | 10709 isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE)); |
10699 current->GetOwnElementKeys(*current_keys, NONE); | 10710 current->GetOwnElementKeys(*current_keys, NONE); |
10700 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 10711 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
10701 isolate, keys, FixedArray::UnionOfKeys(keys, current_keys)); | 10712 isolate, keys, FixedArray::UnionOfKeys(keys, current_keys)); |
10702 } | 10713 } |
10703 // Erase any keys >= length. | 10714 // Erase any keys >= length. |
10704 // TODO(adamk): Remove this step when the contract of %GetArrayKeys | 10715 // TODO(adamk): Remove this step when the contract of %GetArrayKeys |
10705 // is changed to let this happen on the JS side. | 10716 // is changed to let this happen on the JS side. |
10706 for (int i = 0; i < keys->length(); i++) { | 10717 for (int i = 0; i < keys->length(); i++) { |
(...skipping 2141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12848 Object); | 12859 Object); |
12849 | 12860 |
12850 Handle<Object> result; | 12861 Handle<Object> result; |
12851 ASSIGN_RETURN_ON_EXCEPTION( | 12862 ASSIGN_RETURN_ON_EXCEPTION( |
12852 isolate, result, | 12863 isolate, result, |
12853 Execution::Call(isolate, eval_fun, receiver, 0, NULL), | 12864 Execution::Call(isolate, eval_fun, receiver, 0, NULL), |
12854 Object); | 12865 Object); |
12855 | 12866 |
12856 // Skip the global proxy as it has no properties and always delegates to the | 12867 // Skip the global proxy as it has no properties and always delegates to the |
12857 // real global object. | 12868 // real global object. |
12858 if (result->IsJSGlobalProxy()) { | 12869 if (result->IsJSGlobalProxy()) { |
Toon Verwaest
2014/07/11 09:41:28
We should revisit walking beyond the JSGlobalProxy
| |
12859 result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate))); | 12870 PrototypeIterator iter(isolate, result); |
12871 result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | |
12860 } | 12872 } |
12861 | 12873 |
12862 // Clear the oneshot breakpoints so that the debugger does not step further. | 12874 // Clear the oneshot breakpoints so that the debugger does not step further. |
12863 isolate->debug()->ClearStepping(); | 12875 isolate->debug()->ClearStepping(); |
12864 return result; | 12876 return result; |
12865 } | 12877 } |
12866 | 12878 |
12867 | 12879 |
12868 // Evaluate a piece of JavaScript in the context of a stack frame for | 12880 // Evaluate a piece of JavaScript in the context of a stack frame for |
12869 // debugging. Things that need special attention are: | 12881 // debugging. Things that need special attention are: |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13025 if (obj->IsJSContextExtensionObject() || | 13037 if (obj->IsJSContextExtensionObject() || |
13026 obj->map()->constructor() == arguments_function) { | 13038 obj->map()->constructor() == arguments_function) { |
13027 continue; | 13039 continue; |
13028 } | 13040 } |
13029 | 13041 |
13030 // Check if the JS object has a reference to the object looked for. | 13042 // Check if the JS object has a reference to the object looked for. |
13031 if (obj->ReferencesObject(target)) { | 13043 if (obj->ReferencesObject(target)) { |
13032 // Check instance filter if supplied. This is normally used to avoid | 13044 // Check instance filter if supplied. This is normally used to avoid |
13033 // references from mirror objects (see Runtime_IsInPrototypeChain). | 13045 // references from mirror objects (see Runtime_IsInPrototypeChain). |
13034 if (!instance_filter->IsUndefined()) { | 13046 if (!instance_filter->IsUndefined()) { |
13035 Object* V = obj; | 13047 for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd(); |
13036 while (true) { | 13048 iter.Advance()) { |
13037 Object* prototype = V->GetPrototype(isolate); | 13049 if (iter.GetCurrent() == instance_filter) { |
13038 if (prototype->IsNull()) { | |
13039 break; | |
13040 } | |
13041 if (instance_filter == prototype) { | |
13042 obj = NULL; // Don't add this object. | 13050 obj = NULL; // Don't add this object. |
13043 break; | 13051 break; |
13044 } | 13052 } |
13045 V = prototype; | |
13046 } | 13053 } |
13047 } | 13054 } |
13048 | 13055 |
13049 if (obj != NULL) { | 13056 if (obj != NULL) { |
13050 // Valid reference found add to instance array if supplied an update | 13057 // Valid reference found add to instance array if supplied an update |
13051 // count. | 13058 // count. |
13052 if (instances != NULL && count < instances_size) { | 13059 if (instances != NULL && count < instances_size) { |
13053 instances->set(count, obj); | 13060 instances->set(count, obj); |
13054 } | 13061 } |
13055 last = obj; | 13062 last = obj; |
(...skipping 2049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15105 } | 15112 } |
15106 return NULL; | 15113 return NULL; |
15107 } | 15114 } |
15108 | 15115 |
15109 | 15116 |
15110 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15117 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15111 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15118 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15112 } | 15119 } |
15113 | 15120 |
15114 } } // namespace v8::internal | 15121 } } // namespace v8::internal |
OLD | NEW |