OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 9230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9241 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. | 9241 // We need to follow the spec and simulate a call to [[GetOwnProperty]]. |
9242 return JSProxy::cast(pt)->GetElementAttributeWithHandler( | 9242 return JSProxy::cast(pt)->GetElementAttributeWithHandler( |
9243 receiver, index) != ABSENT; | 9243 receiver, index) != ABSENT; |
9244 } | 9244 } |
9245 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 9245 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
9246 } | 9246 } |
9247 | 9247 |
9248 | 9248 |
9249 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 9249 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, |
9250 Object* value, | 9250 Object* value, |
| 9251 PropertyAttributes attributes, |
9251 StrictModeFlag strict_mode, | 9252 StrictModeFlag strict_mode, |
9252 bool check_prototype) { | 9253 bool check_prototype, |
| 9254 SetPropertyMode set_mode) { |
9253 Isolate* isolate = GetIsolate(); | 9255 Isolate* isolate = GetIsolate(); |
9254 // Make sure that the top context does not change when doing | 9256 // Make sure that the top context does not change when doing |
9255 // callbacks or interceptor calls. | 9257 // callbacks or interceptor calls. |
9256 AssertNoContextChange ncc; | 9258 AssertNoContextChange ncc; |
9257 HandleScope scope(isolate); | 9259 HandleScope scope(isolate); |
9258 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 9260 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
9259 Handle<JSObject> this_handle(this); | 9261 Handle<JSObject> this_handle(this); |
9260 Handle<Object> value_handle(value, isolate); | 9262 Handle<Object> value_handle(value, isolate); |
9261 if (!interceptor->setter()->IsUndefined()) { | 9263 if (!interceptor->setter()->IsUndefined()) { |
9262 v8::IndexedPropertySetter setter = | 9264 v8::IndexedPropertySetter setter = |
9263 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 9265 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); |
9264 LOG(isolate, | 9266 LOG(isolate, |
9265 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 9267 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
9266 CustomArguments args(isolate, interceptor->data(), this, this); | 9268 CustomArguments args(isolate, interceptor->data(), this, this); |
9267 v8::AccessorInfo info(args.end()); | 9269 v8::AccessorInfo info(args.end()); |
9268 v8::Handle<v8::Value> result; | 9270 v8::Handle<v8::Value> result; |
9269 { | 9271 { |
9270 // Leaving JavaScript. | 9272 // Leaving JavaScript. |
9271 VMState state(isolate, EXTERNAL); | 9273 VMState state(isolate, EXTERNAL); |
9272 result = setter(index, v8::Utils::ToLocal(value_handle), info); | 9274 result = setter(index, v8::Utils::ToLocal(value_handle), info); |
9273 } | 9275 } |
9274 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 9276 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
9275 if (!result.IsEmpty()) return *value_handle; | 9277 if (!result.IsEmpty()) return *value_handle; |
9276 } | 9278 } |
9277 MaybeObject* raw_result = | 9279 MaybeObject* raw_result = |
9278 this_handle->SetElementWithoutInterceptor(index, | 9280 this_handle->SetElementWithoutInterceptor(index, |
9279 *value_handle, | 9281 *value_handle, |
| 9282 attributes, |
9280 strict_mode, | 9283 strict_mode, |
9281 check_prototype); | 9284 check_prototype, |
| 9285 set_mode); |
9282 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 9286 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
9283 return raw_result; | 9287 return raw_result; |
9284 } | 9288 } |
9285 | 9289 |
9286 | 9290 |
9287 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 9291 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
9288 Object* structure, | 9292 Object* structure, |
9289 uint32_t index, | 9293 uint32_t index, |
9290 Object* holder) { | 9294 Object* holder) { |
9291 Isolate* isolate = GetIsolate(); | 9295 Isolate* isolate = GetIsolate(); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9469 if ((index - capacity) < kMaxGap) { | 9473 if ((index - capacity) < kMaxGap) { |
9470 new_capacity = NewElementsCapacity(index + 1); | 9474 new_capacity = NewElementsCapacity(index + 1); |
9471 ASSERT(new_capacity > index); | 9475 ASSERT(new_capacity > index); |
9472 if (!ShouldConvertToSlowElements(new_capacity)) { | 9476 if (!ShouldConvertToSlowElements(new_capacity)) { |
9473 convert_to_slow = false; | 9477 convert_to_slow = false; |
9474 } | 9478 } |
9475 } | 9479 } |
9476 if (convert_to_slow) { | 9480 if (convert_to_slow) { |
9477 MaybeObject* result = NormalizeElements(); | 9481 MaybeObject* result = NormalizeElements(); |
9478 if (result->IsFailure()) return result; | 9482 if (result->IsFailure()) return result; |
9479 return SetDictionaryElement(index, value, strict_mode, check_prototype); | 9483 return SetDictionaryElement(index, value, NONE, strict_mode, |
| 9484 check_prototype); |
9480 } | 9485 } |
9481 } | 9486 } |
9482 // Convert to fast double elements if appropriate. | 9487 // Convert to fast double elements if appropriate. |
9483 if (HasFastSmiOnlyElements() && !value->IsSmi() && value->IsNumber()) { | 9488 if (HasFastSmiOnlyElements() && !value->IsSmi() && value->IsNumber()) { |
9484 MaybeObject* maybe = | 9489 MaybeObject* maybe = |
9485 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); | 9490 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); |
9486 if (maybe->IsFailure()) return maybe; | 9491 if (maybe->IsFailure()) return maybe; |
9487 FixedDoubleArray::cast(elements())->set(index, value->Number()); | 9492 FixedDoubleArray::cast(elements())->set(index, value->Number()); |
9488 return value; | 9493 return value; |
9489 } | 9494 } |
(...skipping 29 matching lines...) Expand all Loading... |
9519 backing_store->set(index, value); | 9524 backing_store->set(index, value); |
9520 if (must_update_array_length) { | 9525 if (must_update_array_length) { |
9521 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); | 9526 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); |
9522 } | 9527 } |
9523 return value; | 9528 return value; |
9524 } | 9529 } |
9525 | 9530 |
9526 | 9531 |
9527 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, | 9532 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, |
9528 Object* value, | 9533 Object* value, |
| 9534 PropertyAttributes attributes, |
9529 StrictModeFlag strict_mode, | 9535 StrictModeFlag strict_mode, |
9530 bool check_prototype) { | 9536 bool check_prototype, |
| 9537 SetPropertyMode set_mode) { |
9531 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 9538 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
9532 Isolate* isolate = GetIsolate(); | 9539 Isolate* isolate = GetIsolate(); |
9533 Heap* heap = isolate->heap(); | 9540 Heap* heap = isolate->heap(); |
9534 | 9541 |
9535 // Insert element in the dictionary. | 9542 // Insert element in the dictionary. |
9536 FixedArray* elements = FixedArray::cast(this->elements()); | 9543 FixedArray* elements = FixedArray::cast(this->elements()); |
9537 bool is_arguments = | 9544 bool is_arguments = |
9538 (elements->map() == heap->non_strict_arguments_elements_map()); | 9545 (elements->map() == heap->non_strict_arguments_elements_map()); |
9539 SeededNumberDictionary* dictionary = NULL; | 9546 SeededNumberDictionary* dictionary = NULL; |
9540 if (is_arguments) { | 9547 if (is_arguments) { |
9541 dictionary = SeededNumberDictionary::cast(elements->get(1)); | 9548 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
9542 } else { | 9549 } else { |
9543 dictionary = SeededNumberDictionary::cast(elements); | 9550 dictionary = SeededNumberDictionary::cast(elements); |
9544 } | 9551 } |
9545 | 9552 |
9546 int entry = dictionary->FindEntry(index); | 9553 int entry = dictionary->FindEntry(index); |
9547 if (entry != SeededNumberDictionary::kNotFound) { | 9554 if (entry != SeededNumberDictionary::kNotFound) { |
9548 Object* element = dictionary->ValueAt(entry); | 9555 Object* element = dictionary->ValueAt(entry); |
9549 PropertyDetails details = dictionary->DetailsAt(entry); | 9556 PropertyDetails details = dictionary->DetailsAt(entry); |
9550 if (details.type() == CALLBACKS) { | 9557 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { |
9551 return SetElementWithCallback(element, index, value, this, strict_mode); | 9558 return SetElementWithCallback(element, index, value, this, strict_mode); |
9552 } else { | 9559 } else { |
9553 dictionary->UpdateMaxNumberKey(index); | 9560 dictionary->UpdateMaxNumberKey(index); |
9554 // If a value has not been initialized we allow writing to it even if it | 9561 // If a value has not been initialized we allow writing to it even if it |
9555 // is read-only (a declared const that has not been initialized). | 9562 // is read-only (a declared const that has not been initialized). If a |
9556 if (!dictionary->DetailsAt(entry).IsReadOnly() || | 9563 // value is being defined we skip attribute checks completely. |
9557 dictionary->ValueAt(entry)->IsTheHole()) { | 9564 if (set_mode == DEFINE_PROPERTY) { |
| 9565 details = PropertyDetails(attributes, NORMAL, details.index()); |
| 9566 dictionary->ValueAtPut(entry, value); |
| 9567 dictionary->DetailsAtPut(entry, details); |
| 9568 } else if (!details.IsReadOnly() || element->IsTheHole()) { |
9558 dictionary->ValueAtPut(entry, value); | 9569 dictionary->ValueAtPut(entry, value); |
9559 } else if (strict_mode == kStrictMode) { | 9570 } else if (strict_mode == kStrictMode) { |
9560 Handle<Object> holder(this); | 9571 Handle<Object> holder(this); |
9561 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 9572 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
9562 Handle<Object> args[2] = { number, holder }; | 9573 Handle<Object> args[2] = { number, holder }; |
9563 Handle<Object> error = | 9574 Handle<Object> error = |
9564 isolate->factory()->NewTypeError("strict_read_only_property", | 9575 isolate->factory()->NewTypeError("strict_read_only_property", |
9565 HandleVector(args, 2)); | 9576 HandleVector(args, 2)); |
9566 return isolate->Throw(*error); | 9577 return isolate->Throw(*error); |
9567 } | 9578 } |
(...skipping 16 matching lines...) Expand all Loading... |
9584 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 9595 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
9585 Handle<String> name = isolate->factory()->NumberToString(number); | 9596 Handle<String> name = isolate->factory()->NumberToString(number); |
9586 Handle<Object> args[1] = { name }; | 9597 Handle<Object> args[1] = { name }; |
9587 Handle<Object> error = | 9598 Handle<Object> error = |
9588 isolate->factory()->NewTypeError("object_not_extensible", | 9599 isolate->factory()->NewTypeError("object_not_extensible", |
9589 HandleVector(args, 1)); | 9600 HandleVector(args, 1)); |
9590 return isolate->Throw(*error); | 9601 return isolate->Throw(*error); |
9591 } | 9602 } |
9592 } | 9603 } |
9593 FixedArrayBase* new_dictionary; | 9604 FixedArrayBase* new_dictionary; |
9594 MaybeObject* maybe = dictionary->AtNumberPut(index, value); | 9605 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 9606 MaybeObject* maybe = dictionary->AddNumberEntry(index, value, details); |
9595 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; | 9607 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; |
9596 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { | 9608 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { |
9597 if (is_arguments) { | 9609 if (is_arguments) { |
9598 elements->set(1, new_dictionary); | 9610 elements->set(1, new_dictionary); |
9599 } else { | 9611 } else { |
9600 set_elements(new_dictionary); | 9612 set_elements(new_dictionary); |
9601 } | 9613 } |
9602 dictionary = SeededNumberDictionary::cast(new_dictionary); | 9614 dictionary = SeededNumberDictionary::cast(new_dictionary); |
9603 } | 9615 } |
9604 } | 9616 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9725 | 9737 |
9726 // Otherwise default to slow case. | 9738 // Otherwise default to slow case. |
9727 ASSERT(HasFastDoubleElements()); | 9739 ASSERT(HasFastDoubleElements()); |
9728 ASSERT(map()->has_fast_double_elements()); | 9740 ASSERT(map()->has_fast_double_elements()); |
9729 ASSERT(elements()->IsFixedDoubleArray()); | 9741 ASSERT(elements()->IsFixedDoubleArray()); |
9730 Object* obj; | 9742 Object* obj; |
9731 { MaybeObject* maybe_obj = NormalizeElements(); | 9743 { MaybeObject* maybe_obj = NormalizeElements(); |
9732 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9744 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
9733 } | 9745 } |
9734 ASSERT(HasDictionaryElements()); | 9746 ASSERT(HasDictionaryElements()); |
9735 return SetElement(index, value, strict_mode, check_prototype); | 9747 return SetElement(index, value, NONE, strict_mode, check_prototype); |
9736 } | 9748 } |
9737 | 9749 |
9738 | 9750 |
9739 MaybeObject* JSReceiver::SetElement(uint32_t index, | 9751 MaybeObject* JSReceiver::SetElement(uint32_t index, |
9740 Object* value, | 9752 Object* value, |
| 9753 PropertyAttributes attributes, |
9741 StrictModeFlag strict_mode, | 9754 StrictModeFlag strict_mode, |
9742 bool check_proto) { | 9755 bool check_proto) { |
9743 return IsJSProxy() | 9756 if (IsJSProxy()) { |
9744 ? JSProxy::cast(this)->SetElementWithHandler(index, value, strict_mode) | 9757 return JSProxy::cast(this)->SetElementWithHandler( |
9745 : JSObject::cast(this)->SetElement(index, value, strict_mode, check_proto) | 9758 index, value, strict_mode); |
9746 ; | 9759 } else { |
| 9760 return JSObject::cast(this)->SetElement( |
| 9761 index, value, attributes, strict_mode, check_proto); |
| 9762 } |
9747 } | 9763 } |
9748 | 9764 |
9749 | 9765 |
9750 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, | 9766 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
9751 uint32_t index, | 9767 uint32_t index, |
9752 Handle<Object> value, | 9768 Handle<Object> value, |
9753 StrictModeFlag strict_mode) { | 9769 StrictModeFlag strict_mode) { |
9754 ASSERT(!object->HasExternalArrayElements()); | 9770 ASSERT(!object->HasExternalArrayElements()); |
9755 CALL_HEAP_FUNCTION(object->GetIsolate(), | 9771 CALL_HEAP_FUNCTION( |
9756 object->SetElement(index, *value, strict_mode, false), | 9772 object->GetIsolate(), |
9757 Object); | 9773 object->SetElement(index, *value, NONE, strict_mode, false), |
| 9774 Object); |
9758 } | 9775 } |
9759 | 9776 |
9760 | 9777 |
9761 Handle<Object> JSObject::SetElement(Handle<JSObject> object, | 9778 Handle<Object> JSObject::SetElement(Handle<JSObject> object, |
9762 uint32_t index, | 9779 uint32_t index, |
9763 Handle<Object> value, | 9780 Handle<Object> value, |
9764 StrictModeFlag strict_mode) { | 9781 PropertyAttributes attr, |
| 9782 StrictModeFlag strict_mode, |
| 9783 SetPropertyMode set_mode) { |
9765 if (object->HasExternalArrayElements()) { | 9784 if (object->HasExternalArrayElements()) { |
9766 if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) { | 9785 if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) { |
9767 bool has_exception; | 9786 bool has_exception; |
9768 Handle<Object> number = Execution::ToNumber(value, &has_exception); | 9787 Handle<Object> number = Execution::ToNumber(value, &has_exception); |
9769 if (has_exception) return Handle<Object>(); | 9788 if (has_exception) return Handle<Object>(); |
9770 value = number; | 9789 value = number; |
9771 } | 9790 } |
9772 } | 9791 } |
9773 CALL_HEAP_FUNCTION(object->GetIsolate(), | 9792 CALL_HEAP_FUNCTION( |
9774 object->SetElement(index, *value, strict_mode, true), | 9793 object->GetIsolate(), |
9775 Object); | 9794 object->SetElement(index, *value, attr, strict_mode, true, set_mode), |
| 9795 Object); |
9776 } | 9796 } |
9777 | 9797 |
9778 | 9798 |
9779 MaybeObject* JSObject::SetElement(uint32_t index, | 9799 MaybeObject* JSObject::SetElement(uint32_t index, |
9780 Object* value, | 9800 Object* value, |
| 9801 PropertyAttributes attributes, |
9781 StrictModeFlag strict_mode, | 9802 StrictModeFlag strict_mode, |
9782 bool check_prototype) { | 9803 bool check_prototype, |
| 9804 SetPropertyMode set_mode) { |
9783 // Check access rights if needed. | 9805 // Check access rights if needed. |
9784 if (IsAccessCheckNeeded()) { | 9806 if (IsAccessCheckNeeded()) { |
9785 Heap* heap = GetHeap(); | 9807 Heap* heap = GetHeap(); |
9786 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 9808 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
9787 HandleScope scope(heap->isolate()); | 9809 HandleScope scope(heap->isolate()); |
9788 Handle<Object> value_handle(value); | 9810 Handle<Object> value_handle(value); |
9789 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 9811 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
9790 return *value_handle; | 9812 return *value_handle; |
9791 } | 9813 } |
9792 } | 9814 } |
9793 | 9815 |
9794 if (IsJSGlobalProxy()) { | 9816 if (IsJSGlobalProxy()) { |
9795 Object* proto = GetPrototype(); | 9817 Object* proto = GetPrototype(); |
9796 if (proto->IsNull()) return value; | 9818 if (proto->IsNull()) return value; |
9797 ASSERT(proto->IsJSGlobalObject()); | 9819 ASSERT(proto->IsJSGlobalObject()); |
9798 return JSObject::cast(proto)->SetElement(index, | 9820 return JSObject::cast(proto)->SetElement(index, |
9799 value, | 9821 value, |
| 9822 attributes, |
9800 strict_mode, | 9823 strict_mode, |
9801 check_prototype); | 9824 check_prototype, |
| 9825 set_mode); |
| 9826 } |
| 9827 |
| 9828 // Don't allow element properties to be redefined for external arrays. |
| 9829 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { |
| 9830 Isolate* isolate = GetHeap()->isolate(); |
| 9831 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 9832 Handle<Object> args[] = { Handle<Object>(this), number }; |
| 9833 Handle<Object> error = isolate->factory()->NewTypeError( |
| 9834 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
| 9835 return isolate->Throw(*error); |
| 9836 } |
| 9837 |
| 9838 // Normalize the elements to enable attributes on the property. |
| 9839 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
| 9840 SeededNumberDictionary* dictionary; |
| 9841 MaybeObject* maybe_object = NormalizeElements(); |
| 9842 if (!maybe_object->To(&dictionary)) return maybe_object; |
| 9843 // Make sure that we never go back to fast case. |
| 9844 dictionary->set_requires_slow_elements(); |
9802 } | 9845 } |
9803 | 9846 |
9804 // Check for lookup interceptor | 9847 // Check for lookup interceptor |
9805 if (HasIndexedInterceptor()) { | 9848 if (HasIndexedInterceptor()) { |
9806 return SetElementWithInterceptor(index, | 9849 return SetElementWithInterceptor(index, |
9807 value, | 9850 value, |
| 9851 attributes, |
9808 strict_mode, | 9852 strict_mode, |
9809 check_prototype); | 9853 check_prototype, |
| 9854 set_mode); |
9810 } | 9855 } |
9811 | 9856 |
9812 return SetElementWithoutInterceptor(index, | 9857 return SetElementWithoutInterceptor(index, |
9813 value, | 9858 value, |
| 9859 attributes, |
9814 strict_mode, | 9860 strict_mode, |
9815 check_prototype); | 9861 check_prototype, |
| 9862 set_mode); |
9816 } | 9863 } |
9817 | 9864 |
9818 | 9865 |
9819 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 9866 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
9820 Object* value, | 9867 Object* value, |
| 9868 PropertyAttributes attr, |
9821 StrictModeFlag strict_mode, | 9869 StrictModeFlag strict_mode, |
9822 bool check_prototype) { | 9870 bool check_prototype, |
| 9871 SetPropertyMode set_mode) { |
| 9872 ASSERT(HasDictionaryElements() || |
| 9873 HasDictionaryArgumentsElements() || |
| 9874 (attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); |
9823 Isolate* isolate = GetIsolate(); | 9875 Isolate* isolate = GetIsolate(); |
9824 switch (GetElementsKind()) { | 9876 switch (GetElementsKind()) { |
9825 case FAST_SMI_ONLY_ELEMENTS: | 9877 case FAST_SMI_ONLY_ELEMENTS: |
9826 case FAST_ELEMENTS: | 9878 case FAST_ELEMENTS: |
9827 return SetFastElement(index, value, strict_mode, check_prototype); | 9879 return SetFastElement(index, value, strict_mode, check_prototype); |
9828 case FAST_DOUBLE_ELEMENTS: | 9880 case FAST_DOUBLE_ELEMENTS: |
9829 return SetFastDoubleElement(index, value, strict_mode, check_prototype); | 9881 return SetFastDoubleElement(index, value, strict_mode, check_prototype); |
9830 case EXTERNAL_PIXEL_ELEMENTS: { | 9882 case EXTERNAL_PIXEL_ELEMENTS: { |
9831 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 9883 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
9832 return pixels->SetValue(index, value); | 9884 return pixels->SetValue(index, value); |
(...skipping 27 matching lines...) Expand all Loading... |
9860 } | 9912 } |
9861 case EXTERNAL_FLOAT_ELEMENTS: { | 9913 case EXTERNAL_FLOAT_ELEMENTS: { |
9862 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); | 9914 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); |
9863 return array->SetValue(index, value); | 9915 return array->SetValue(index, value); |
9864 } | 9916 } |
9865 case EXTERNAL_DOUBLE_ELEMENTS: { | 9917 case EXTERNAL_DOUBLE_ELEMENTS: { |
9866 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); | 9918 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); |
9867 return array->SetValue(index, value); | 9919 return array->SetValue(index, value); |
9868 } | 9920 } |
9869 case DICTIONARY_ELEMENTS: | 9921 case DICTIONARY_ELEMENTS: |
9870 return SetDictionaryElement(index, value, strict_mode, check_prototype); | 9922 return SetDictionaryElement(index, value, attr, strict_mode, |
| 9923 check_prototype, set_mode); |
9871 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 9924 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
9872 FixedArray* parameter_map = FixedArray::cast(elements()); | 9925 FixedArray* parameter_map = FixedArray::cast(elements()); |
9873 uint32_t length = parameter_map->length(); | 9926 uint32_t length = parameter_map->length(); |
9874 Object* probe = | 9927 Object* probe = |
9875 (index < length - 2) ? parameter_map->get(index + 2) : NULL; | 9928 (index < length - 2) ? parameter_map->get(index + 2) : NULL; |
9876 if (probe != NULL && !probe->IsTheHole()) { | 9929 if (probe != NULL && !probe->IsTheHole()) { |
9877 Context* context = Context::cast(parameter_map->get(0)); | 9930 Context* context = Context::cast(parameter_map->get(0)); |
9878 int context_index = Smi::cast(probe)->value(); | 9931 int context_index = Smi::cast(probe)->value(); |
9879 ASSERT(!context->get(context_index)->IsTheHole()); | 9932 ASSERT(!context->get(context_index)->IsTheHole()); |
9880 context->set(context_index, value); | 9933 context->set(context_index, value); |
9881 return value; | 9934 return value; |
9882 } else { | 9935 } else { |
9883 // Object is not mapped, defer to the arguments. | 9936 // Object is not mapped, defer to the arguments. |
9884 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 9937 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
9885 if (arguments->IsDictionary()) { | 9938 if (arguments->IsDictionary()) { |
9886 return SetDictionaryElement(index, value, strict_mode, | 9939 return SetDictionaryElement(index, value, attr, strict_mode, |
9887 check_prototype); | 9940 check_prototype, set_mode); |
9888 } else { | 9941 } else { |
9889 return SetFastElement(index, value, strict_mode, check_prototype); | 9942 return SetFastElement(index, value, strict_mode, check_prototype); |
9890 } | 9943 } |
9891 } | 9944 } |
9892 } | 9945 } |
9893 } | 9946 } |
9894 // All possible cases have been handled above. Add a return to avoid the | 9947 // All possible cases have been handled above. Add a return to avoid the |
9895 // complaints from the compiler. | 9948 // complaints from the compiler. |
9896 UNREACHABLE(); | 9949 UNREACHABLE(); |
9897 return isolate->heap()->null_value(); | 9950 return isolate->heap()->null_value(); |
(...skipping 3187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13085 if (break_point_objects()->IsUndefined()) return 0; | 13138 if (break_point_objects()->IsUndefined()) return 0; |
13086 // Single break point. | 13139 // Single break point. |
13087 if (!break_point_objects()->IsFixedArray()) return 1; | 13140 if (!break_point_objects()->IsFixedArray()) return 1; |
13088 // Multiple break points. | 13141 // Multiple break points. |
13089 return FixedArray::cast(break_point_objects())->length(); | 13142 return FixedArray::cast(break_point_objects())->length(); |
13090 } | 13143 } |
13091 #endif // ENABLE_DEBUGGER_SUPPORT | 13144 #endif // ENABLE_DEBUGGER_SUPPORT |
13092 | 13145 |
13093 | 13146 |
13094 } } // namespace v8::internal | 13147 } } // namespace v8::internal |
OLD | NEW |