| 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.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 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, 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 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 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |