Chromium Code Reviews| Index: src/elements.cc |
| diff --git a/src/elements.cc b/src/elements.cc |
| index 5e7a84e38b8377a6009a93ecc4967832f168dc19..44cec30e12fb0a0ea4af1b834da99c4bdfbd25a3 100644 |
| --- a/src/elements.cc |
| +++ b/src/elements.cc |
| @@ -91,6 +91,16 @@ class ElementsAccessorBase : public ElementsAccessor { |
| return backing_store->GetHeap()->the_hole_value(); |
| } |
| + virtual MaybeObject* Set(JSObject* obj, |
| + uint32_t key, |
| + Object* value, |
| + PropertyAttributes attributes) = 0; |
|
danno
2011/10/24 21:09:02
Use CRTP here. The virtual Set method should call
|
| + |
| + virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, |
|
danno
2011/10/24 21:09:02
Can you get away with a single Set wrapper in the
|
| + uint32_t index, |
| + Object* value, |
| + PropertyAttributes attributes) = 0; |
| + |
| virtual MaybeObject* Delete(JSObject* obj, |
| uint32_t key, |
| JSReceiver::DeleteMode mode) = 0; |
| @@ -272,6 +282,36 @@ class FastElementsAccessor |
| } |
| protected: |
| + virtual MaybeObject* Set(JSObject* obj, |
| + uint32_t key, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + // Normalize the elements to enable attributes on the element and make |
| + // sure that we never go back to fast case. |
| + if (attributes != NONE && attributes != ABSENT) { |
| + MaybeObject* maybe_dictionary = obj->NormalizeElements(); |
| + NumberDictionary* dictionary; |
| + if (!maybe_dictionary->To(&dictionary)) { |
| + return maybe_dictionary; |
| + } |
| + dictionary->set_requires_slow_elements(); |
| + return ForKind(DICTIONARY_ELEMENTS)->Set(obj, key, value, attributes); |
| + } |
| + |
| + // TODO(mstarzinger): Not yet implemented. |
| + UNREACHABLE(); |
| + return NULL; |
| + } |
| + |
| + virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, |
| + uint32_t index, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + // TODO(mstarzinger): Not yet implemented. |
| + UNREACHABLE(); |
| + return NULL; |
| + } |
| + |
| virtual MaybeObject* Delete(JSObject* obj, |
| uint32_t key, |
| JSReceiver::DeleteMode mode) { |
| @@ -287,6 +327,36 @@ class FastDoubleElementsAccessor |
| friend class ElementsAccessorBase<FastDoubleElementsAccessor, |
| FixedDoubleArray>; |
| + virtual MaybeObject* Set(JSObject* obj, |
| + uint32_t key, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + // Normalize the elements to enable attributes on the element and make |
| + // sure that we never go back to fast case. |
| + if (attributes != NONE && attributes != ABSENT) { |
| + MaybeObject* maybe_dictionary = obj->NormalizeElements(); |
| + NumberDictionary* dictionary; |
| + if (!maybe_dictionary->To(&dictionary)) { |
| + return maybe_dictionary; |
| + } |
| + dictionary->set_requires_slow_elements(); |
| + return ForKind(DICTIONARY_ELEMENTS)->Set(obj, key, value, attributes); |
| + } |
| + |
| + // TODO(mstarzinger): Not yet implemented. |
| + UNREACHABLE(); |
| + return NULL; |
| + } |
| + |
| + virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, |
| + uint32_t index, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + // TODO(mstarzinger): Not yet implemented. |
| + UNREACHABLE(); |
| + return NULL; |
| + } |
| + |
| virtual MaybeObject* Delete(JSObject* obj, |
| uint32_t key, |
| JSReceiver::DeleteMode mode) { |
| @@ -329,6 +399,27 @@ class ExternalElementsAccessor |
| } |
| } |
| + virtual MaybeObject* Set(JSObject* obj, |
| + uint32_t key, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + // There is no way to set attributes for external elements. |
| + ASSERT(attributes == NONE || attributes == ABSENT); |
| + |
| + // TODO(mstarzinger): Not yet implemented. |
| + UNREACHABLE(); |
| + return NULL; |
| + } |
| + |
| + virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, |
| + uint32_t index, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + // TODO(mstarzinger): Not yet implemented. |
| + UNREACHABLE(); |
| + return NULL; |
| + } |
| + |
| virtual MaybeObject* Delete(JSObject* obj, |
| uint32_t key, |
| JSReceiver::DeleteMode mode) { |
| @@ -444,6 +535,32 @@ class DictionaryElementsAccessor |
| friend class ElementsAccessorBase<DictionaryElementsAccessor, |
| NumberDictionary>; |
| + virtual MaybeObject* Set(JSObject* obj, |
| + uint32_t key, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + NumberDictionary* dictionary = NumberDictionary::cast(obj->elements()); |
| + MaybeObject* maybe_elements = |
| + SetInternal(dictionary, key, value, attributes); |
| + FixedArray* new_elements; |
| + if (!maybe_elements->To(&new_elements)) { |
| + return maybe_elements; |
| + } |
| + if (new_elements != dictionary) { |
| + obj->set_elements(new_elements); |
| + } |
| + return value; |
| + } |
| + |
| + virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, |
| + uint32_t key, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + NumberDictionary* dictionary = NumberDictionary::cast(backing_store); |
| + PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| + return dictionary->Set(key, value, details); |
| + } |
| + |
| virtual MaybeObject* Delete(JSObject* obj, |
| uint32_t key, |
| JSReceiver::DeleteMode mode) { |
| @@ -505,9 +622,52 @@ class NonStrictArgumentsElementsAccessor |
| } |
| } |
| + virtual MaybeObject* Set(JSObject* obj, |
| + uint32_t key, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + // Normalize the elements to enable attributes on the element and make |
| + // sure that we never go back to fast case. |
| + if (attributes != NONE && attributes != ABSENT) { |
| + MaybeObject* maybe_dictionary = obj->NormalizeElements(); |
| + NumberDictionary* dictionary; |
| + if (!maybe_dictionary->To(&dictionary)) { |
| + return maybe_dictionary; |
| + } |
| + dictionary->set_requires_slow_elements(); |
| + |
| + // Object is not mapped, defer to the arguments. |
| + FixedArray* parameter_map = FixedArray::cast(obj->elements()); |
| + FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| + MaybeObject* maybe_elements = ElementsAccessor::ForArray(arguments)-> |
| + SetInternal(arguments, key, value, attributes); |
| + FixedArray* new_elements; |
| + if (!maybe_elements->To(&new_elements)) { |
| + return maybe_elements; |
| + } |
| + if (new_elements != arguments) { |
| + parameter_map->set(1, new_elements); |
| + } |
| + |
| + return value; |
| + } |
| + |
| + // TODO(mstarzinger): Not yet implemented. |
| + UNREACHABLE(); |
| + return NULL; |
| + } |
| + |
| + virtual MaybeObject* SetInternal(FixedArrayBase* backing_store, |
| + uint32_t index, |
| + Object* value, |
| + PropertyAttributes attributes) { |
| + // The non-strict arguments object itself cannot be a backing store. |
| + UNREACHABLE(); |
| + return NULL; |
| + } |
| + |
| virtual MaybeObject* Delete(JSObject* obj, |
| - uint32_t key |
| - , |
| + uint32_t key, |
| JSReceiver::DeleteMode mode) { |
| FixedArray* parameter_map = FixedArray::cast(obj->elements()); |
| Object* probe = GetParameterMapArg(parameter_map, key); |