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

Side by Side Diff: src/objects.cc

Issue 6577036: [Isolates] Merge from bleeding_edge to isolates, revisions 6100-6300. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 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/objects.h ('k') | src/objects-debug.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1845 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 1856 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
1857 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; 1857 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return;
1858 } 1858 }
1859 result->NotFound(); 1859 result->NotFound();
1860 } 1860 }
1861 1861
1862 1862
1863 // We only need to deal with CALLBACKS and INTERCEPTORS 1863 // We only need to deal with CALLBACKS and INTERCEPTORS
1864 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, 1864 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,
1865 String* name, 1865 String* name,
1866 Object* value) { 1866 Object* value,
1867 bool check_prototype) {
1867 Heap* heap = GetHeap(); 1868 Heap* heap = GetHeap();
1868 if (!result->IsProperty()) { 1869 if (check_prototype && !result->IsProperty()) {
1869 LookupCallbackSetterInPrototypes(name, result); 1870 LookupCallbackSetterInPrototypes(name, result);
1870 } 1871 }
1871 1872
1872 if (result->IsProperty()) { 1873 if (result->IsProperty()) {
1873 if (!result->IsReadOnly()) { 1874 if (!result->IsReadOnly()) {
1874 switch (result->type()) { 1875 switch (result->type()) {
1875 case CALLBACKS: { 1876 case CALLBACKS: {
1876 Object* obj = result->GetCallbackObject(); 1877 Object* obj = result->GetCallbackObject();
1877 if (obj->IsAccessorInfo()) { 1878 if (obj->IsAccessorInfo()) {
1878 AccessorInfo* info = AccessorInfo::cast(obj); 1879 AccessorInfo* info = AccessorInfo::cast(obj);
1879 if (info->all_can_write()) { 1880 if (info->all_can_write()) {
1880 return SetPropertyWithCallback(result->GetCallbackObject(), 1881 return SetPropertyWithCallback(result->GetCallbackObject(),
1881 name, 1882 name,
1882 value, 1883 value,
1883 result->holder()); 1884 result->holder());
1884 } 1885 }
1885 } 1886 }
1886 break; 1887 break;
1887 } 1888 }
1888 case INTERCEPTOR: { 1889 case INTERCEPTOR: {
1889 // Try lookup real named properties. Note that only property can be 1890 // Try lookup real named properties. Note that only property can be
1890 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. 1891 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.
1891 LookupResult r; 1892 LookupResult r;
1892 LookupRealNamedProperty(name, &r); 1893 LookupRealNamedProperty(name, &r);
1893 if (r.IsProperty()) { 1894 if (r.IsProperty()) {
1894 return SetPropertyWithFailedAccessCheck(&r, name, value); 1895 return SetPropertyWithFailedAccessCheck(&r, name, value,
1896 check_prototype);
1895 } 1897 }
1896 break; 1898 break;
1897 } 1899 }
1898 default: { 1900 default: {
1899 break; 1901 break;
1900 } 1902 }
1901 } 1903 }
1902 } 1904 }
1903 } 1905 }
1904 1906
(...skipping 21 matching lines...) Expand all
1926 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name); 1928 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name);
1927 if (maybe_symbol_version->ToObject(&symbol_version)) { 1929 if (maybe_symbol_version->ToObject(&symbol_version)) {
1928 name = String::cast(symbol_version); 1930 name = String::cast(symbol_version);
1929 } 1931 }
1930 } 1932 }
1931 } 1933 }
1932 1934
1933 // Check access rights if needed. 1935 // Check access rights if needed.
1934 if (IsAccessCheckNeeded() 1936 if (IsAccessCheckNeeded()
1935 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { 1937 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
1936 return SetPropertyWithFailedAccessCheck(result, name, value); 1938 return SetPropertyWithFailedAccessCheck(result, name, value, true);
1937 } 1939 }
1938 1940
1939 if (IsJSGlobalProxy()) { 1941 if (IsJSGlobalProxy()) {
1940 Object* proto = GetPrototype(); 1942 Object* proto = GetPrototype();
1941 if (proto->IsNull()) return value; 1943 if (proto->IsNull()) return value;
1942 ASSERT(proto->IsJSGlobalObject()); 1944 ASSERT(proto->IsJSGlobalObject());
1943 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); 1945 return JSObject::cast(proto)->SetProperty(result, name, value, attributes);
1944 } 1946 }
1945 1947
1946 if (!result->IsProperty() && !IsJSContextExtensionObject()) { 1948 if (!result->IsProperty() && !IsJSContextExtensionObject()) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2016 return value; 2018 return value;
2017 } 2019 }
2018 2020
2019 2021
2020 // Set a real local property, even if it is READ_ONLY. If the property is not 2022 // Set a real local property, even if it is READ_ONLY. If the property is not
2021 // present, add it with attributes NONE. This code is an exact clone of 2023 // present, add it with attributes NONE. This code is an exact clone of
2022 // SetProperty, with the check for IsReadOnly and the check for a 2024 // SetProperty, with the check for IsReadOnly and the check for a
2023 // callback setter removed. The two lines looking up the LookupResult 2025 // callback setter removed. The two lines looking up the LookupResult
2024 // result are also added. If one of the functions is changed, the other 2026 // result are also added. If one of the functions is changed, the other
2025 // should be. 2027 // should be.
2026 MaybeObject* JSObject::IgnoreAttributesAndSetLocalProperty( 2028 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
2027 String* name, 2029 String* name,
2028 Object* value, 2030 Object* value,
2029 PropertyAttributes attributes) { 2031 PropertyAttributes attributes) {
2030 Heap* heap = GetHeap(); 2032 Heap* heap = GetHeap();
2031 2033
2032 // Make sure that the top context does not change when doing callbacks or 2034 // Make sure that the top context does not change when doing callbacks or
2033 // interceptor calls. 2035 // interceptor calls.
2034 AssertNoContextChange ncc; 2036 AssertNoContextChange ncc;
2035 LookupResult result; 2037 LookupResult result;
2036 LocalLookup(name, &result); 2038 LocalLookup(name, &result);
2037 // Check access rights if needed. 2039 // Check access rights if needed.
2038 if (IsAccessCheckNeeded() 2040 if (IsAccessCheckNeeded()
2039 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { 2041 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
2040 return SetPropertyWithFailedAccessCheck(&result, name, value); 2042 return SetPropertyWithFailedAccessCheck(&result, name, value, false);
2041 } 2043 }
2042 2044
2043 if (IsJSGlobalProxy()) { 2045 if (IsJSGlobalProxy()) {
2044 Object* proto = GetPrototype(); 2046 Object* proto = GetPrototype();
2045 if (proto->IsNull()) return value; 2047 if (proto->IsNull()) return value;
2046 ASSERT(proto->IsJSGlobalObject()); 2048 ASSERT(proto->IsJSGlobalObject());
2047 return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty( 2049 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes(
2048 name, 2050 name,
2049 value, 2051 value,
2050 attributes); 2052 attributes);
2051 } 2053 }
2052 2054
2053 // Check for accessor in prototype chain removed here in clone. 2055 // Check for accessor in prototype chain removed here in clone.
2054 if (!result.IsFound()) { 2056 if (!result.IsFound()) {
2055 // Neither properties nor transitions found. 2057 // Neither properties nor transitions found.
2056 return AddProperty(name, value, attributes); 2058 return AddProperty(name, value, attributes);
2057 } 2059 }
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 2994
2993 // Try to flatten before operating on the string. 2995 // Try to flatten before operating on the string.
2994 name->TryFlatten(); 2996 name->TryFlatten();
2995 2997
2996 if (!CanSetCallback(name)) { 2998 if (!CanSetCallback(name)) {
2997 return heap->undefined_value(); 2999 return heap->undefined_value();
2998 } 3000 }
2999 3001
3000 uint32_t index = 0; 3002 uint32_t index = 0;
3001 bool is_element = name->AsArrayIndex(&index); 3003 bool is_element = name->AsArrayIndex(&index);
3002 if (is_element && IsJSArray()) return heap->undefined_value();
3003 3004
3004 if (is_element) { 3005 if (is_element) {
3005 switch (GetElementsKind()) { 3006 switch (GetElementsKind()) {
3006 case FAST_ELEMENTS: 3007 case FAST_ELEMENTS:
3007 break; 3008 break;
3008 case PIXEL_ELEMENTS: 3009 case PIXEL_ELEMENTS:
3009 case EXTERNAL_BYTE_ELEMENTS: 3010 case EXTERNAL_BYTE_ELEMENTS:
3010 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3011 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3011 case EXTERNAL_SHORT_ELEMENTS: 3012 case EXTERNAL_SHORT_ELEMENTS:
3012 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3013 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
(...skipping 2214 matching lines...) Expand 10 before | Expand all | Expand 10 after
5227 decoder->Reset(str.start(), str.length()); 5228 decoder->Reset(str.start(), str.length());
5228 int i; 5229 int i;
5229 for (i = 0; i < slen && decoder->has_more(); i++) { 5230 for (i = 0; i < slen && decoder->has_more(); i++) {
5230 uc32 r = decoder->GetNext(); 5231 uc32 r = decoder->GetNext();
5231 if (Get(i) != r) return false; 5232 if (Get(i) != r) return false;
5232 } 5233 }
5233 return i == slen && !decoder->has_more(); 5234 return i == slen && !decoder->has_more();
5234 } 5235 }
5235 5236
5236 5237
5238 bool String::IsAsciiEqualTo(Vector<const char> str) {
5239 int slen = length();
5240 if (str.length() != slen) return false;
5241 for (int i = 0; i < slen; i++) {
5242 if (Get(i) != static_cast<uint16_t>(str[i])) return false;
5243 }
5244 return true;
5245 }
5246
5247
5248 bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
5249 int slen = length();
5250 if (str.length() != slen) return false;
5251 for (int i = 0; i < slen; i++) {
5252 if (Get(i) != str[i]) return false;
5253 }
5254 return true;
5255 }
5256
5257
5237 template <typename schar> 5258 template <typename schar>
5238 static inline uint32_t HashSequentialString(const schar* chars, int length) { 5259 static inline uint32_t HashSequentialString(const schar* chars, int length) {
5239 StringHasher hasher(length); 5260 StringHasher hasher(length);
5240 if (!hasher.has_trivial_hash()) { 5261 if (!hasher.has_trivial_hash()) {
5241 int i; 5262 int i;
5242 for (i = 0; hasher.is_array_index() && (i < length); i++) { 5263 for (i = 0; hasher.is_array_index() && (i < length); i++) {
5243 hasher.AddCharacter(chars[i]); 5264 hasher.AddCharacter(chars[i]);
5244 } 5265 }
5245 for (; i < length; i++) { 5266 for (; i < length; i++) {
5246 hasher.AddCharacterNoIndex(chars[i]); 5267 hasher.AddCharacterNoIndex(chars[i]);
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
6067 if (statement_position < p && p <= position) { 6088 if (statement_position < p && p <= position) {
6068 statement_position = p; 6089 statement_position = p;
6069 } 6090 }
6070 } 6091 }
6071 it.next(); 6092 it.next();
6072 } 6093 }
6073 return statement_position; 6094 return statement_position;
6074 } 6095 }
6075 6096
6076 6097
6077 uint8_t* Code::GetSafepointEntry(Address pc) { 6098 SafepointEntry Code::GetSafepointEntry(Address pc) {
6078 SafepointTable table(this); 6099 SafepointTable table(this);
6079 unsigned pc_offset = static_cast<unsigned>(pc - instruction_start()); 6100 return table.FindEntry(pc);
6080 for (unsigned i = 0; i < table.length(); i++) {
6081 // TODO(kasperl): Replace the linear search with binary search.
6082 if (table.GetPcOffset(i) == pc_offset) return table.GetEntry(i);
6083 }
6084 return NULL;
6085 } 6101 }
6086 6102
6087 6103
6088 void Code::SetNoStackCheckTable() { 6104 void Code::SetNoStackCheckTable() {
6089 // Indicate the absence of a stack-check table by a table start after the 6105 // Indicate the absence of a stack-check table by a table start after the
6090 // end of the instructions. Table start must be aligned, so round up. 6106 // end of the instructions. Table start must be aligned, so round up.
6091 set_stack_check_table_start(RoundUp(instruction_size(), kIntSize)); 6107 set_stack_check_table_start(RoundUp(instruction_size(), kIntSize));
6092 } 6108 }
6093 6109
6094 6110
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
6345 #endif 6361 #endif
6346 6362
6347 if (kind() == OPTIMIZED_FUNCTION) { 6363 if (kind() == OPTIMIZED_FUNCTION) {
6348 SafepointTable table(this); 6364 SafepointTable table(this);
6349 PrintF(out, "Safepoints (size = %u)\n", table.size()); 6365 PrintF(out, "Safepoints (size = %u)\n", table.size());
6350 for (unsigned i = 0; i < table.length(); i++) { 6366 for (unsigned i = 0; i < table.length(); i++) {
6351 unsigned pc_offset = table.GetPcOffset(i); 6367 unsigned pc_offset = table.GetPcOffset(i);
6352 PrintF(out, "%p %4d ", (instruction_start() + pc_offset), pc_offset); 6368 PrintF(out, "%p %4d ", (instruction_start() + pc_offset), pc_offset);
6353 table.PrintEntry(i); 6369 table.PrintEntry(i);
6354 PrintF(out, " (sp -> fp)"); 6370 PrintF(out, " (sp -> fp)");
6355 int deoptimization_index = table.GetDeoptimizationIndex(i); 6371 SafepointEntry entry = table.GetEntry(i);
6356 if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) { 6372 if (entry.deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
6357 PrintF(out, " %6d", deoptimization_index); 6373 PrintF(out, " %6d", entry.deoptimization_index());
6358 } else { 6374 } else {
6359 PrintF(out, " <none>"); 6375 PrintF(out, " <none>");
6360 } 6376 }
6377 if (entry.argument_count() > 0) {
6378 PrintF(out, " argc: %d", entry.argument_count());
6379 }
6361 PrintF(out, "\n"); 6380 PrintF(out, "\n");
6362 } 6381 }
6363 PrintF(out, "\n"); 6382 PrintF(out, "\n");
6364 } else if (kind() == FUNCTION) { 6383 } else if (kind() == FUNCTION) {
6365 unsigned offset = stack_check_table_start(); 6384 unsigned offset = stack_check_table_start();
6366 // If there is no stack check table, the "table start" will at or after 6385 // If there is no stack check table, the "table start" will at or after
6367 // (due to alignment) the end of the instruction stream. 6386 // (due to alignment) the end of the instruction stream.
6368 if (static_cast<int>(offset) < instruction_size()) { 6387 if (static_cast<int>(offset) < instruction_size()) {
6369 unsigned* address = 6388 unsigned* address =
6370 reinterpret_cast<unsigned*>(instruction_start() + offset); 6389 reinterpret_cast<unsigned*>(instruction_start() + offset);
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
6886 // Handle [] on String objects. 6905 // Handle [] on String objects.
6887 if (this->IsStringObjectWithCharacterAt(index)) return true; 6906 if (this->IsStringObjectWithCharacterAt(index)) return true;
6888 6907
6889 Object* pt = GetPrototype(); 6908 Object* pt = GetPrototype();
6890 if (pt->IsNull()) return false; 6909 if (pt->IsNull()) return false;
6891 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 6910 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
6892 } 6911 }
6893 6912
6894 6913
6895 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, 6914 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index,
6896 Object* value) { 6915 Object* value,
6916 bool check_prototype) {
6897 Isolate* isolate = GetIsolate(); 6917 Isolate* isolate = GetIsolate();
6898 // Make sure that the top context does not change when doing 6918 // Make sure that the top context does not change when doing
6899 // callbacks or interceptor calls. 6919 // callbacks or interceptor calls.
6900 AssertNoContextChange ncc; 6920 AssertNoContextChange ncc;
6901 HandleScope scope(isolate); 6921 HandleScope scope(isolate);
6902 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 6922 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
6903 Handle<JSObject> this_handle(this); 6923 Handle<JSObject> this_handle(this);
6904 Handle<Object> value_handle(value, isolate); 6924 Handle<Object> value_handle(value, isolate);
6905 if (!interceptor->setter()->IsUndefined()) { 6925 if (!interceptor->setter()->IsUndefined()) {
6906 v8::IndexedPropertySetter setter = 6926 v8::IndexedPropertySetter setter =
6907 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); 6927 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter());
6908 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); 6928 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index));
6909 CustomArguments args(isolate, interceptor->data(), this, this); 6929 CustomArguments args(isolate, interceptor->data(), this, this);
6910 v8::AccessorInfo info(args.end()); 6930 v8::AccessorInfo info(args.end());
6911 v8::Handle<v8::Value> result; 6931 v8::Handle<v8::Value> result;
6912 { 6932 {
6913 // Leaving JavaScript. 6933 // Leaving JavaScript.
6914 VMState state(isolate, EXTERNAL); 6934 VMState state(isolate, EXTERNAL);
6915 result = setter(index, v8::Utils::ToLocal(value_handle), info); 6935 result = setter(index, v8::Utils::ToLocal(value_handle), info);
6916 } 6936 }
6917 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 6937 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
6918 if (!result.IsEmpty()) return *value_handle; 6938 if (!result.IsEmpty()) return *value_handle;
6919 } 6939 }
6920 MaybeObject* raw_result = 6940 MaybeObject* raw_result =
6921 this_handle->SetElementWithoutInterceptor(index, *value_handle); 6941 this_handle->SetElementWithoutInterceptor(index,
6942 *value_handle,
6943 check_prototype);
6922 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 6944 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
6923 return raw_result; 6945 return raw_result;
6924 } 6946 }
6925 6947
6926 6948
6927 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, 6949 MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
6928 Object* structure, 6950 Object* structure,
6929 uint32_t index, 6951 uint32_t index,
6930 Object* holder) { 6952 Object* holder) {
6931 Isolate* isolate = GetIsolate(); 6953 Isolate* isolate = GetIsolate();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
7025 } 7047 }
7026 7048
7027 UNREACHABLE(); 7049 UNREACHABLE();
7028 return NULL; 7050 return NULL;
7029 } 7051 }
7030 7052
7031 7053
7032 // Adding n elements in fast case is O(n*n). 7054 // Adding n elements in fast case is O(n*n).
7033 // Note: revisit design to have dual undefined values to capture absent 7055 // Note: revisit design to have dual undefined values to capture absent
7034 // elements. 7056 // elements.
7035 MaybeObject* JSObject::SetFastElement(uint32_t index, Object* value) { 7057 MaybeObject* JSObject::SetFastElement(uint32_t index,
7058 Object* value,
7059 bool check_prototype) {
7036 ASSERT(HasFastElements()); 7060 ASSERT(HasFastElements());
7037 7061
7038 Object* elms_obj; 7062 Object* elms_obj;
7039 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); 7063 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements();
7040 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; 7064 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
7041 } 7065 }
7042 FixedArray* elms = FixedArray::cast(elms_obj); 7066 FixedArray* elms = FixedArray::cast(elms_obj);
7043 uint32_t elms_length = static_cast<uint32_t>(elms->length()); 7067 uint32_t elms_length = static_cast<uint32_t>(elms->length());
7044 7068
7045 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { 7069 if (check_prototype &&
7046 if (SetElementWithCallbackSetterInPrototypes(index, value)) { 7070 (index >= elms_length || elms->get(index)->IsTheHole()) &&
7047 return value; 7071 SetElementWithCallbackSetterInPrototypes(index, value)) {
7048 } 7072 return value;
7049 } 7073 }
7050 7074
7075
7051 // Check whether there is extra space in fixed array.. 7076 // Check whether there is extra space in fixed array..
7052 if (index < elms_length) { 7077 if (index < elms_length) {
7053 elms->set(index, value); 7078 elms->set(index, value);
7054 if (IsJSArray()) { 7079 if (IsJSArray()) {
7055 // Update the length of the array if needed. 7080 // Update the length of the array if needed.
7056 uint32_t array_length = 0; 7081 uint32_t array_length = 0;
7057 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 7082 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
7058 if (index >= array_length) { 7083 if (index >= array_length) {
7059 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 7084 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
7060 } 7085 }
(...skipping 17 matching lines...) Expand all
7078 return value; 7103 return value;
7079 } 7104 }
7080 } 7105 }
7081 7106
7082 // Otherwise default to slow case. 7107 // Otherwise default to slow case.
7083 Object* obj; 7108 Object* obj;
7084 { MaybeObject* maybe_obj = NormalizeElements(); 7109 { MaybeObject* maybe_obj = NormalizeElements();
7085 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7110 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7086 } 7111 }
7087 ASSERT(HasDictionaryElements()); 7112 ASSERT(HasDictionaryElements());
7088 return SetElement(index, value); 7113 return SetElement(index, value, check_prototype);
7089 } 7114 }
7090 7115
7091 7116
7092 MaybeObject* JSObject::SetElement(uint32_t index, Object* value) { 7117 MaybeObject* JSObject::SetElement(uint32_t index,
7118 Object* value,
7119 bool check_prototype) {
7093 Heap* heap = GetHeap(); 7120 Heap* heap = GetHeap();
7094 // Check access rights if needed. 7121 // Check access rights if needed.
7095 if (IsAccessCheckNeeded() && 7122 if (IsAccessCheckNeeded() &&
7096 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { 7123 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) {
7097 HandleScope scope; 7124 HandleScope scope;
7098 Handle<Object> value_handle(value); 7125 Handle<Object> value_handle(value);
7099 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); 7126 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
7100 return *value_handle; 7127 return *value_handle;
7101 } 7128 }
7102 7129
7103 if (IsJSGlobalProxy()) { 7130 if (IsJSGlobalProxy()) {
7104 Object* proto = GetPrototype(); 7131 Object* proto = GetPrototype();
7105 if (proto->IsNull()) return value; 7132 if (proto->IsNull()) return value;
7106 ASSERT(proto->IsJSGlobalObject()); 7133 ASSERT(proto->IsJSGlobalObject());
7107 return JSObject::cast(proto)->SetElement(index, value); 7134 return JSObject::cast(proto)->SetElement(index, value, check_prototype);
7108 } 7135 }
7109 7136
7110 // Check for lookup interceptor 7137 // Check for lookup interceptor
7111 if (HasIndexedInterceptor()) { 7138 if (HasIndexedInterceptor()) {
7112 return SetElementWithInterceptor(index, value); 7139 return SetElementWithInterceptor(index, value, check_prototype);
7113 } 7140 }
7114 7141
7115 return SetElementWithoutInterceptor(index, value); 7142 return SetElementWithoutInterceptor(index, value, check_prototype);
7116 } 7143 }
7117 7144
7118 7145
7119 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 7146 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
7120 Object* value) { 7147 Object* value,
7148 bool check_prototype) {
7121 Heap* heap = GetHeap(); 7149 Heap* heap = GetHeap();
7122 switch (GetElementsKind()) { 7150 switch (GetElementsKind()) {
7123 case FAST_ELEMENTS: 7151 case FAST_ELEMENTS:
7124 // Fast case. 7152 // Fast case.
7125 return SetFastElement(index, value); 7153 return SetFastElement(index, value, check_prototype);
7126 case PIXEL_ELEMENTS: { 7154 case PIXEL_ELEMENTS: {
7127 PixelArray* pixels = PixelArray::cast(elements()); 7155 PixelArray* pixels = PixelArray::cast(elements());
7128 return pixels->SetValue(index, value); 7156 return pixels->SetValue(index, value);
7129 } 7157 }
7130 case EXTERNAL_BYTE_ELEMENTS: { 7158 case EXTERNAL_BYTE_ELEMENTS: {
7131 ExternalByteArray* array = ExternalByteArray::cast(elements()); 7159 ExternalByteArray* array = ExternalByteArray::cast(elements());
7132 return array->SetValue(index, value); 7160 return array->SetValue(index, value);
7133 } 7161 }
7134 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { 7162 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
7135 ExternalUnsignedByteArray* array = 7163 ExternalUnsignedByteArray* array =
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
7168 Object* element = dictionary->ValueAt(entry); 7196 Object* element = dictionary->ValueAt(entry);
7169 PropertyDetails details = dictionary->DetailsAt(entry); 7197 PropertyDetails details = dictionary->DetailsAt(entry);
7170 if (details.type() == CALLBACKS) { 7198 if (details.type() == CALLBACKS) {
7171 return SetElementWithCallback(element, index, value, this); 7199 return SetElementWithCallback(element, index, value, this);
7172 } else { 7200 } else {
7173 dictionary->UpdateMaxNumberKey(index); 7201 dictionary->UpdateMaxNumberKey(index);
7174 dictionary->ValueAtPut(entry, value); 7202 dictionary->ValueAtPut(entry, value);
7175 } 7203 }
7176 } else { 7204 } else {
7177 // Index not already used. Look for an accessor in the prototype chain. 7205 // Index not already used. Look for an accessor in the prototype chain.
7178 if (!IsJSArray()) { 7206 if (check_prototype &&
7179 if (SetElementWithCallbackSetterInPrototypes(index, value)) { 7207 SetElementWithCallbackSetterInPrototypes(index, value)) {
7180 return value; 7208 return value;
7181 }
7182 } 7209 }
7183 // When we set the is_extensible flag to false we always force 7210 // When we set the is_extensible flag to false we always force
7184 // the element into dictionary mode (and force them to stay there). 7211 // the element into dictionary mode (and force them to stay there).
7185 if (!map()->is_extensible()) { 7212 if (!map()->is_extensible()) {
7186 Handle<Object> number(FACTORY->NewNumberFromUint(index)); 7213 Handle<Object> number(FACTORY->NewNumberFromUint(index));
7187 Handle<String> index_string(FACTORY->NumberToString(number)); 7214 Handle<String> index_string(FACTORY->NumberToString(number));
7188 Handle<Object> args[1] = { index_string }; 7215 Handle<Object> args[1] = { index_string };
7189 return heap->isolate()->Throw( 7216 return heap->isolate()->Throw(
7190 *FACTORY->NewTypeError("object_not_extensible", 7217 *FACTORY->NewTypeError("object_not_extensible",
7191 HandleVector(args, 1))); 7218 HandleVector(args, 1)));
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after
8169 return Isolate::Current()->heap()->AllocateSymbol( 8196 return Isolate::Current()->heap()->AllocateSymbol(
8170 string_, chars_, hash_field_); 8197 string_, chars_, hash_field_);
8171 } 8198 }
8172 8199
8173 Vector<const char> string_; 8200 Vector<const char> string_;
8174 uint32_t hash_field_; 8201 uint32_t hash_field_;
8175 int chars_; // Caches the number of characters when computing the hash code. 8202 int chars_; // Caches the number of characters when computing the hash code.
8176 }; 8203 };
8177 8204
8178 8205
8206 template <typename Char>
8207 class SequentialSymbolKey : public HashTableKey {
8208 public:
8209 explicit SequentialSymbolKey(Vector<const Char> string)
8210 : string_(string), hash_field_(0) { }
8211
8212 uint32_t Hash() {
8213 StringHasher hasher(string_.length());
8214
8215 // Very long strings have a trivial hash that doesn't inspect the
8216 // string contents.
8217 if (hasher.has_trivial_hash()) {
8218 hash_field_ = hasher.GetHashField();
8219 } else {
8220 int i = 0;
8221 // Do the iterative array index computation as long as there is a
8222 // chance this is an array index.
8223 while (i < string_.length() && hasher.is_array_index()) {
8224 hasher.AddCharacter(static_cast<uc32>(string_[i]));
8225 i++;
8226 }
8227
8228 // Process the remaining characters without updating the array
8229 // index.
8230 while (i < string_.length()) {
8231 hasher.AddCharacterNoIndex(static_cast<uc32>(string_[i]));
8232 i++;
8233 }
8234 hash_field_ = hasher.GetHashField();
8235 }
8236
8237 uint32_t result = hash_field_ >> String::kHashShift;
8238 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
8239 return result;
8240 }
8241
8242
8243 uint32_t HashForObject(Object* other) {
8244 return String::cast(other)->Hash();
8245 }
8246
8247 Vector<const Char> string_;
8248 uint32_t hash_field_;
8249 };
8250
8251
8252
8253 class AsciiSymbolKey : public SequentialSymbolKey<char> {
8254 public:
8255 explicit AsciiSymbolKey(Vector<const char> str)
8256 : SequentialSymbolKey<char>(str) { }
8257
8258 bool IsMatch(Object* string) {
8259 return String::cast(string)->IsAsciiEqualTo(string_);
8260 }
8261
8262 MaybeObject* AsObject() {
8263 if (hash_field_ == 0) Hash();
8264 return HEAP->AllocateAsciiSymbol(string_, hash_field_);
8265 }
8266 };
8267
8268
8269 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> {
8270 public:
8271 explicit TwoByteSymbolKey(Vector<const uc16> str)
8272 : SequentialSymbolKey<uc16>(str) { }
8273
8274 bool IsMatch(Object* string) {
8275 return String::cast(string)->IsTwoByteEqualTo(string_);
8276 }
8277
8278 MaybeObject* AsObject() {
8279 if (hash_field_ == 0) Hash();
8280 return HEAP->AllocateTwoByteSymbol(string_, hash_field_);
8281 }
8282 };
8283
8284
8179 // SymbolKey carries a string/symbol object as key. 8285 // SymbolKey carries a string/symbol object as key.
8180 class SymbolKey : public HashTableKey { 8286 class SymbolKey : public HashTableKey {
8181 public: 8287 public:
8182 explicit SymbolKey(String* string) 8288 explicit SymbolKey(String* string)
8183 : string_(string) { } 8289 : string_(string) { }
8184 8290
8185 bool IsMatch(Object* string) { 8291 bool IsMatch(Object* string) {
8186 return String::cast(string)->Equals(string_); 8292 return String::cast(string)->Equals(string_);
8187 } 8293 }
8188 8294
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
8905 } 9011 }
8906 } 9012 }
8907 9013
8908 9014
8909 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { 9015 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) {
8910 Utf8SymbolKey key(str); 9016 Utf8SymbolKey key(str);
8911 return LookupKey(&key, s); 9017 return LookupKey(&key, s);
8912 } 9018 }
8913 9019
8914 9020
9021 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str,
9022 Object** s) {
9023 AsciiSymbolKey key(str);
9024 return LookupKey(&key, s);
9025 }
9026
9027
9028 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str,
9029 Object** s) {
9030 TwoByteSymbolKey key(str);
9031 return LookupKey(&key, s);
9032 }
9033
8915 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { 9034 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
8916 int entry = FindEntry(key); 9035 int entry = FindEntry(key);
8917 9036
8918 // Symbol already in table. 9037 // Symbol already in table.
8919 if (entry != kNotFound) { 9038 if (entry != kNotFound) {
8920 *s = KeyAt(entry); 9039 *s = KeyAt(entry);
8921 return this; 9040 return this;
8922 } 9041 }
8923 9042
8924 // Adding new symbol. Grow table if needed. 9043 // Adding new symbol. Grow table if needed.
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
9846 if (break_point_objects()->IsUndefined()) return 0; 9965 if (break_point_objects()->IsUndefined()) return 0;
9847 // Single beak point. 9966 // Single beak point.
9848 if (!break_point_objects()->IsFixedArray()) return 1; 9967 if (!break_point_objects()->IsFixedArray()) return 1;
9849 // Multiple break points. 9968 // Multiple break points.
9850 return FixedArray::cast(break_point_objects())->length(); 9969 return FixedArray::cast(break_point_objects())->length();
9851 } 9970 }
9852 #endif 9971 #endif
9853 9972
9854 9973
9855 } } // namespace v8::internal 9974 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698