| OLD | NEW |
| 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 1980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1991 return AddProperty(name, value, attributes); | 1991 return AddProperty(name, value, attributes); |
| 1992 } | 1992 } |
| 1993 if (result->IsReadOnly() && result->IsProperty()) { | 1993 if (result->IsReadOnly() && result->IsProperty()) { |
| 1994 if (strict_mode == kStrictMode) { | 1994 if (strict_mode == kStrictMode) { |
| 1995 HandleScope scope; | 1995 HandleScope scope; |
| 1996 Handle<String> key(name); | 1996 Handle<String> key(name); |
| 1997 Handle<Object> holder(this); | 1997 Handle<Object> holder(this); |
| 1998 Handle<Object> args[2] = { key, holder }; | 1998 Handle<Object> args[2] = { key, holder }; |
| 1999 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( | 1999 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( |
| 2000 "strict_read_only_property", HandleVector(args, 2))); | 2000 "strict_read_only_property", HandleVector(args, 2))); |
| 2001 | |
| 2002 } else { | 2001 } else { |
| 2003 return value; | 2002 return value; |
| 2004 } | 2003 } |
| 2005 } | 2004 } |
| 2006 // This is a real property that is not read-only, or it is a | 2005 // This is a real property that is not read-only, or it is a |
| 2007 // transition or null descriptor and there are no setters in the prototypes. | 2006 // transition or null descriptor and there are no setters in the prototypes. |
| 2008 switch (result->type()) { | 2007 switch (result->type()) { |
| 2009 case NORMAL: | 2008 case NORMAL: |
| 2010 return SetNormalizedProperty(result, value); | 2009 return SetNormalizedProperty(result, value); |
| 2011 case FIELD: | 2010 case FIELD: |
| (...skipping 5002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7014 if (this->IsStringObjectWithCharacterAt(index)) return true; | 7013 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 7015 | 7014 |
| 7016 Object* pt = GetPrototype(); | 7015 Object* pt = GetPrototype(); |
| 7017 if (pt->IsNull()) return false; | 7016 if (pt->IsNull()) return false; |
| 7018 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 7017 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 7019 } | 7018 } |
| 7020 | 7019 |
| 7021 | 7020 |
| 7022 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 7021 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, |
| 7023 Object* value, | 7022 Object* value, |
| 7023 StrictModeFlag strict_mode, |
| 7024 bool check_prototype) { | 7024 bool check_prototype) { |
| 7025 Isolate* isolate = GetIsolate(); | 7025 Isolate* isolate = GetIsolate(); |
| 7026 // Make sure that the top context does not change when doing | 7026 // Make sure that the top context does not change when doing |
| 7027 // callbacks or interceptor calls. | 7027 // callbacks or interceptor calls. |
| 7028 AssertNoContextChange ncc; | 7028 AssertNoContextChange ncc; |
| 7029 HandleScope scope(isolate); | 7029 HandleScope scope(isolate); |
| 7030 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 7030 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 7031 Handle<JSObject> this_handle(this); | 7031 Handle<JSObject> this_handle(this); |
| 7032 Handle<Object> value_handle(value, isolate); | 7032 Handle<Object> value_handle(value, isolate); |
| 7033 if (!interceptor->setter()->IsUndefined()) { | 7033 if (!interceptor->setter()->IsUndefined()) { |
| 7034 v8::IndexedPropertySetter setter = | 7034 v8::IndexedPropertySetter setter = |
| 7035 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 7035 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); |
| 7036 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 7036 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
| 7037 CustomArguments args(isolate, interceptor->data(), this, this); | 7037 CustomArguments args(isolate, interceptor->data(), this, this); |
| 7038 v8::AccessorInfo info(args.end()); | 7038 v8::AccessorInfo info(args.end()); |
| 7039 v8::Handle<v8::Value> result; | 7039 v8::Handle<v8::Value> result; |
| 7040 { | 7040 { |
| 7041 // Leaving JavaScript. | 7041 // Leaving JavaScript. |
| 7042 VMState state(isolate, EXTERNAL); | 7042 VMState state(isolate, EXTERNAL); |
| 7043 result = setter(index, v8::Utils::ToLocal(value_handle), info); | 7043 result = setter(index, v8::Utils::ToLocal(value_handle), info); |
| 7044 } | 7044 } |
| 7045 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 7045 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 7046 if (!result.IsEmpty()) return *value_handle; | 7046 if (!result.IsEmpty()) return *value_handle; |
| 7047 } | 7047 } |
| 7048 MaybeObject* raw_result = | 7048 MaybeObject* raw_result = |
| 7049 this_handle->SetElementWithoutInterceptor(index, | 7049 this_handle->SetElementWithoutInterceptor(index, |
| 7050 *value_handle, | 7050 *value_handle, |
| 7051 strict_mode, |
| 7051 check_prototype); | 7052 check_prototype); |
| 7052 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 7053 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 7053 return raw_result; | 7054 return raw_result; |
| 7054 } | 7055 } |
| 7055 | 7056 |
| 7056 | 7057 |
| 7057 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 7058 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
| 7058 Object* structure, | 7059 Object* structure, |
| 7059 uint32_t index, | 7060 uint32_t index, |
| 7060 Object* holder) { | 7061 Object* holder) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7157 UNREACHABLE(); | 7158 UNREACHABLE(); |
| 7158 return NULL; | 7159 return NULL; |
| 7159 } | 7160 } |
| 7160 | 7161 |
| 7161 | 7162 |
| 7162 // Adding n elements in fast case is O(n*n). | 7163 // Adding n elements in fast case is O(n*n). |
| 7163 // Note: revisit design to have dual undefined values to capture absent | 7164 // Note: revisit design to have dual undefined values to capture absent |
| 7164 // elements. | 7165 // elements. |
| 7165 MaybeObject* JSObject::SetFastElement(uint32_t index, | 7166 MaybeObject* JSObject::SetFastElement(uint32_t index, |
| 7166 Object* value, | 7167 Object* value, |
| 7168 StrictModeFlag strict_mode, |
| 7167 bool check_prototype) { | 7169 bool check_prototype) { |
| 7168 ASSERT(HasFastElements()); | 7170 ASSERT(HasFastElements()); |
| 7169 | 7171 |
| 7170 Object* elms_obj; | 7172 Object* elms_obj; |
| 7171 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); | 7173 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); |
| 7172 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 7174 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 7173 } | 7175 } |
| 7174 FixedArray* elms = FixedArray::cast(elms_obj); | 7176 FixedArray* elms = FixedArray::cast(elms_obj); |
| 7175 uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 7177 uint32_t elms_length = static_cast<uint32_t>(elms->length()); |
| 7176 | 7178 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7213 return value; | 7215 return value; |
| 7214 } | 7216 } |
| 7215 } | 7217 } |
| 7216 | 7218 |
| 7217 // Otherwise default to slow case. | 7219 // Otherwise default to slow case. |
| 7218 Object* obj; | 7220 Object* obj; |
| 7219 { MaybeObject* maybe_obj = NormalizeElements(); | 7221 { MaybeObject* maybe_obj = NormalizeElements(); |
| 7220 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7222 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7221 } | 7223 } |
| 7222 ASSERT(HasDictionaryElements()); | 7224 ASSERT(HasDictionaryElements()); |
| 7223 return SetElement(index, value, check_prototype); | 7225 return SetElement(index, value, strict_mode, check_prototype); |
| 7224 } | 7226 } |
| 7225 | 7227 |
| 7226 | 7228 |
| 7227 MaybeObject* JSObject::SetElement(uint32_t index, | 7229 MaybeObject* JSObject::SetElement(uint32_t index, |
| 7228 Object* value, | 7230 Object* value, |
| 7231 StrictModeFlag strict_mode, |
| 7229 bool check_prototype) { | 7232 bool check_prototype) { |
| 7230 Heap* heap = GetHeap(); | 7233 Heap* heap = GetHeap(); |
| 7231 // Check access rights if needed. | 7234 // Check access rights if needed. |
| 7232 if (IsAccessCheckNeeded() && | 7235 if (IsAccessCheckNeeded() && |
| 7233 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 7236 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 7234 HandleScope scope; | 7237 HandleScope scope; |
| 7235 Handle<Object> value_handle(value); | 7238 Handle<Object> value_handle(value); |
| 7236 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 7239 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 7237 return *value_handle; | 7240 return *value_handle; |
| 7238 } | 7241 } |
| 7239 | 7242 |
| 7240 if (IsJSGlobalProxy()) { | 7243 if (IsJSGlobalProxy()) { |
| 7241 Object* proto = GetPrototype(); | 7244 Object* proto = GetPrototype(); |
| 7242 if (proto->IsNull()) return value; | 7245 if (proto->IsNull()) return value; |
| 7243 ASSERT(proto->IsJSGlobalObject()); | 7246 ASSERT(proto->IsJSGlobalObject()); |
| 7244 return JSObject::cast(proto)->SetElement(index, value, check_prototype); | 7247 return JSObject::cast(proto)->SetElement(index, |
| 7248 value, |
| 7249 strict_mode, |
| 7250 check_prototype); |
| 7245 } | 7251 } |
| 7246 | 7252 |
| 7247 // Check for lookup interceptor | 7253 // Check for lookup interceptor |
| 7248 if (HasIndexedInterceptor()) { | 7254 if (HasIndexedInterceptor()) { |
| 7249 return SetElementWithInterceptor(index, value, check_prototype); | 7255 return SetElementWithInterceptor(index, |
| 7256 value, |
| 7257 strict_mode, |
| 7258 check_prototype); |
| 7250 } | 7259 } |
| 7251 | 7260 |
| 7252 return SetElementWithoutInterceptor(index, value, check_prototype); | 7261 return SetElementWithoutInterceptor(index, |
| 7262 value, |
| 7263 strict_mode, |
| 7264 check_prototype); |
| 7253 } | 7265 } |
| 7254 | 7266 |
| 7255 | 7267 |
| 7256 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 7268 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
| 7257 Object* value, | 7269 Object* value, |
| 7270 StrictModeFlag strict_mode, |
| 7258 bool check_prototype) { | 7271 bool check_prototype) { |
| 7259 Heap* heap = GetHeap(); | 7272 Isolate* isolate = GetIsolate(); |
| 7260 switch (GetElementsKind()) { | 7273 switch (GetElementsKind()) { |
| 7261 case FAST_ELEMENTS: | 7274 case FAST_ELEMENTS: |
| 7262 // Fast case. | 7275 // Fast case. |
| 7263 return SetFastElement(index, value, check_prototype); | 7276 return SetFastElement(index, value, strict_mode, check_prototype); |
| 7264 case PIXEL_ELEMENTS: { | 7277 case PIXEL_ELEMENTS: { |
| 7265 PixelArray* pixels = PixelArray::cast(elements()); | 7278 PixelArray* pixels = PixelArray::cast(elements()); |
| 7266 return pixels->SetValue(index, value); | 7279 return pixels->SetValue(index, value); |
| 7267 } | 7280 } |
| 7268 case EXTERNAL_BYTE_ELEMENTS: { | 7281 case EXTERNAL_BYTE_ELEMENTS: { |
| 7269 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 7282 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
| 7270 return array->SetValue(index, value); | 7283 return array->SetValue(index, value); |
| 7271 } | 7284 } |
| 7272 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 7285 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
| 7273 ExternalUnsignedByteArray* array = | 7286 ExternalUnsignedByteArray* array = |
| (...skipping 28 matching lines...) Expand all Loading... |
| 7302 NumberDictionary* dictionary = NumberDictionary::cast(elms); | 7315 NumberDictionary* dictionary = NumberDictionary::cast(elms); |
| 7303 | 7316 |
| 7304 int entry = dictionary->FindEntry(index); | 7317 int entry = dictionary->FindEntry(index); |
| 7305 if (entry != NumberDictionary::kNotFound) { | 7318 if (entry != NumberDictionary::kNotFound) { |
| 7306 Object* element = dictionary->ValueAt(entry); | 7319 Object* element = dictionary->ValueAt(entry); |
| 7307 PropertyDetails details = dictionary->DetailsAt(entry); | 7320 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7308 if (details.type() == CALLBACKS) { | 7321 if (details.type() == CALLBACKS) { |
| 7309 return SetElementWithCallback(element, index, value, this); | 7322 return SetElementWithCallback(element, index, value, this); |
| 7310 } else { | 7323 } else { |
| 7311 dictionary->UpdateMaxNumberKey(index); | 7324 dictionary->UpdateMaxNumberKey(index); |
| 7312 dictionary->ValueAtPut(entry, value); | 7325 // If put fails instrict mode, throw exception. |
| 7326 if (!dictionary->ValueAtPut(entry, value) && |
| 7327 strict_mode == kStrictMode) { |
| 7328 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); |
| 7329 Handle<Object> holder(this); |
| 7330 Handle<Object> args[2] = { number, holder }; |
| 7331 return isolate->Throw( |
| 7332 *isolate->factory()->NewTypeError("strict_read_only_property", |
| 7333 HandleVector(args, 2))); |
| 7334 } |
| 7313 } | 7335 } |
| 7314 } else { | 7336 } else { |
| 7315 // Index not already used. Look for an accessor in the prototype chain. | 7337 // Index not already used. Look for an accessor in the prototype chain. |
| 7316 if (check_prototype) { | 7338 if (check_prototype) { |
| 7317 bool found; | 7339 bool found; |
| 7318 MaybeObject* result = | 7340 MaybeObject* result = |
| 7341 // Strict mode not needed. No-setter case already handled. |
| 7319 SetElementWithCallbackSetterInPrototypes(index, value, &found); | 7342 SetElementWithCallbackSetterInPrototypes(index, value, &found); |
| 7320 if (found) return result; | 7343 if (found) return result; |
| 7321 } | 7344 } |
| 7322 // When we set the is_extensible flag to false we always force | 7345 // When we set the is_extensible flag to false we always force |
| 7323 // the element into dictionary mode (and force them to stay there). | 7346 // the element into dictionary mode (and force them to stay there). |
| 7324 if (!map()->is_extensible()) { | 7347 if (!map()->is_extensible()) { |
| 7325 Handle<Object> number(FACTORY->NewNumberFromUint(index)); | 7348 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); |
| 7326 Handle<String> index_string(FACTORY->NumberToString(number)); | 7349 Handle<String> index_string( |
| 7350 isolate->factory()->NumberToString(number)); |
| 7327 Handle<Object> args[1] = { index_string }; | 7351 Handle<Object> args[1] = { index_string }; |
| 7328 return heap->isolate()->Throw( | 7352 return isolate->Throw( |
| 7329 *FACTORY->NewTypeError("object_not_extensible", | 7353 *isolate->factory()->NewTypeError("object_not_extensible", |
| 7330 HandleVector(args, 1))); | 7354 HandleVector(args, 1))); |
| 7331 } | 7355 } |
| 7332 Object* result; | 7356 Object* result; |
| 7333 { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value); | 7357 { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value); |
| 7334 if (!maybe_result->ToObject(&result)) return maybe_result; | 7358 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 7335 } | 7359 } |
| 7336 if (elms != FixedArray::cast(result)) { | 7360 if (elms != FixedArray::cast(result)) { |
| 7337 set_elements(FixedArray::cast(result)); | 7361 set_elements(FixedArray::cast(result)); |
| 7338 } | 7362 } |
| 7339 } | 7363 } |
| 7340 | 7364 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7373 | 7397 |
| 7374 return value; | 7398 return value; |
| 7375 } | 7399 } |
| 7376 default: | 7400 default: |
| 7377 UNREACHABLE(); | 7401 UNREACHABLE(); |
| 7378 break; | 7402 break; |
| 7379 } | 7403 } |
| 7380 // All possible cases have been handled above. Add a return to avoid the | 7404 // All possible cases have been handled above. Add a return to avoid the |
| 7381 // complaints from the compiler. | 7405 // complaints from the compiler. |
| 7382 UNREACHABLE(); | 7406 UNREACHABLE(); |
| 7383 return heap->null_value(); | 7407 return isolate->heap()->null_value(); |
| 7384 } | 7408 } |
| 7385 | 7409 |
| 7386 | 7410 |
| 7387 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, | 7411 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
| 7388 Object* value) { | 7412 Object* value) { |
| 7389 uint32_t old_len = 0; | 7413 uint32_t old_len = 0; |
| 7390 CHECK(length()->ToArrayIndex(&old_len)); | 7414 CHECK(length()->ToArrayIndex(&old_len)); |
| 7391 // Check to see if we need to update the length. For now, we make | 7415 // Check to see if we need to update the length. For now, we make |
| 7392 // sure that the length stays within 32-bits (unsigned). | 7416 // sure that the length stays within 32-bits (unsigned). |
| 7393 if (index >= old_len && index != 0xffffffff) { | 7417 if (index >= old_len && index != 0xffffffff) { |
| (...skipping 2740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10134 if (break_point_objects()->IsUndefined()) return 0; | 10158 if (break_point_objects()->IsUndefined()) return 0; |
| 10135 // Single beak point. | 10159 // Single beak point. |
| 10136 if (!break_point_objects()->IsFixedArray()) return 1; | 10160 if (!break_point_objects()->IsFixedArray()) return 1; |
| 10137 // Multiple break points. | 10161 // Multiple break points. |
| 10138 return FixedArray::cast(break_point_objects())->length(); | 10162 return FixedArray::cast(break_point_objects())->length(); |
| 10139 } | 10163 } |
| 10140 #endif | 10164 #endif |
| 10141 | 10165 |
| 10142 | 10166 |
| 10143 } } // namespace v8::internal | 10167 } } // namespace v8::internal |
| OLD | NEW |