Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: src/runtime.cc

Issue 376233002: Introduce a PrototypeIterator class and use it for prototype access (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: updates Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/prototype.h ('k') | src/string-stream.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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.AdvanceIgnoringProxies();
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
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, PrototypeIterator::START_AT_RECEIVER);
1880 while (true) { 1888 while (true) {
1881 Handle<Object> prototype = Object::GetPrototype(isolate, V); 1889 iter.AdvanceIgnoringProxies();
1882 if (prototype->IsNull()) return isolate->heap()->false_value(); 1890 if (iter.IsAtEnd()) return isolate->heap()->false_value();
1883 if (*O == *prototype) return isolate->heap()->true_value(); 1891 if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
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
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
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 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after
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()) {
12859 result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate))); 12870 PrototypeIterator iter(isolate, result);
12871 // TODO(verwaest): This will crash when the global proxy is detached.
12872 result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
12860 } 12873 }
12861 12874
12862 // Clear the oneshot breakpoints so that the debugger does not step further. 12875 // Clear the oneshot breakpoints so that the debugger does not step further.
12863 isolate->debug()->ClearStepping(); 12876 isolate->debug()->ClearStepping();
12864 return result; 12877 return result;
12865 } 12878 }
12866 12879
12867 12880
12868 // Evaluate a piece of JavaScript in the context of a stack frame for 12881 // Evaluate a piece of JavaScript in the context of a stack frame for
12869 // debugging. Things that need special attention are: 12882 // debugging. Things that need special attention are:
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
13025 if (obj->IsJSContextExtensionObject() || 13038 if (obj->IsJSContextExtensionObject() ||
13026 obj->map()->constructor() == arguments_function) { 13039 obj->map()->constructor() == arguments_function) {
13027 continue; 13040 continue;
13028 } 13041 }
13029 13042
13030 // Check if the JS object has a reference to the object looked for. 13043 // Check if the JS object has a reference to the object looked for.
13031 if (obj->ReferencesObject(target)) { 13044 if (obj->ReferencesObject(target)) {
13032 // Check instance filter if supplied. This is normally used to avoid 13045 // Check instance filter if supplied. This is normally used to avoid
13033 // references from mirror objects (see Runtime_IsInPrototypeChain). 13046 // references from mirror objects (see Runtime_IsInPrototypeChain).
13034 if (!instance_filter->IsUndefined()) { 13047 if (!instance_filter->IsUndefined()) {
13035 Object* V = obj; 13048 for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
13036 while (true) { 13049 iter.Advance()) {
13037 Object* prototype = V->GetPrototype(isolate); 13050 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. 13051 obj = NULL; // Don't add this object.
13043 break; 13052 break;
13044 } 13053 }
13045 V = prototype;
13046 } 13054 }
13047 } 13055 }
13048 13056
13049 if (obj != NULL) { 13057 if (obj != NULL) {
13050 // Valid reference found add to instance array if supplied an update 13058 // Valid reference found add to instance array if supplied an update
13051 // count. 13059 // count.
13052 if (instances != NULL && count < instances_size) { 13060 if (instances != NULL && count < instances_size) {
13053 instances->set(count, obj); 13061 instances->set(count, obj);
13054 } 13062 }
13055 last = obj; 13063 last = obj;
(...skipping 2049 matching lines...) Expand 10 before | Expand all | Expand 10 after
15105 } 15113 }
15106 return NULL; 15114 return NULL;
15107 } 15115 }
15108 15116
15109 15117
15110 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 15118 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15111 return &(kIntrinsicFunctions[static_cast<int>(id)]); 15119 return &(kIntrinsicFunctions[static_cast<int>(id)]);
15112 } 15120 }
15113 15121
15114 } } // namespace v8::internal 15122 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/prototype.h ('k') | src/string-stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698