class ElementsAccessorBase : public ElementsAccessor {
protected:
explicit ElementsAccessorBase(const char* name) : ElementsAccessor(name) { }
- virtual MaybeObject* Get(FixedArrayBase* backing_store,
+
+ static bool HasElementImpl(Object* receiver,
+ JSObject* holder,
+ uint32_t key,
+ BackingStoreClass* backing_store) {
+ MaybeObject* element =
+ ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store);
+ return !element->IsTheHole();
+ }
+
+ virtual bool HasElement(Object* receiver,
+ JSObject* holder,
+ uint32_t key,
+ FixedArrayBase* backing_store) {
+ if (backing_store == NULL) {
+ backing_store = holder->elements();
+ }
+ return ElementsAccessorSubclass::HasElementImpl(
+ receiver, holder, key, BackingStoreClass::cast(backing_store));
+ }
+
+ virtual MaybeObject* Get(Object* receiver,
+ JSObject* holder,
uint32_t key,
- JSObject* obj,
- Object* receiver) {
+ FixedArrayBase* backing_store) {
+ if (backing_store == NULL) {
+ backing_store = holder->elements();
+ }
return ElementsAccessorSubclass::GetImpl(
- BackingStoreClass::cast(backing_store), key, obj, receiver);
+ receiver, holder, key, BackingStoreClass::cast(backing_store));
}
- static MaybeObject* GetImpl(BackingStoreClass* backing_store,
- uint32_t key,
+ static MaybeObject* GetImpl(Object* receiver,
JSObject* obj,
- Object* receiver) {
+ uint32_t key,
+ BackingStoreClass* backing_store) {
return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
? backing_store->get(key)
: backing_store->GetHeap()->the_hole_value();
}
- virtual MaybeObject* SetLength(JSObject* obj,
+ virtual MaybeObject* SetLength(JSArray* array,
Object* length) {
- ASSERT(obj->IsJSArray());
return ElementsAccessorSubclass::SetLengthImpl(
- BackingStoreClass::cast(obj->elements()), obj, length);
+ array, length, BackingStoreClass::cast(array->elements()));
}
- static MaybeObject* SetLengthImpl(BackingStoreClass* backing_store,
- JSObject* obj,
- Object* length);
+ static MaybeObject* SetLengthImpl(JSObject* obj,
+ Object* length,
+ BackingStoreClass* backing_store);
virtual MaybeObject* SetCapacityAndLength(JSArray* array,
int capacity,
uint32_t key,
JSReceiver::DeleteMode mode) = 0;
- virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from,
- FixedArray* to,
+ virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
JSObject* holder,
- Object* receiver) {
+ FixedArray* to,
+ FixedArrayBase* from) {
int len0 = to->length();
#ifdef DEBUG
if (FLAG_enable_slow_asserts) {
}
}
#endif
+ if (from == NULL) {
+ from = holder->elements();
+ }
BackingStoreClass* backing_store = BackingStoreClass::cast(from);
uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store);
uint32_t key =
ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
if (ElementsAccessorSubclass::HasElementImpl(
- backing_store, key, holder, receiver)) {
+ receiver, holder, key, backing_store)) {
MaybeObject* maybe_value =
- ElementsAccessorSubclass::GetImpl(backing_store, key,
- holder, receiver);
+ ElementsAccessorSubclass::GetImpl(receiver, holder,
+ key, backing_store);
Object* value;
if (!maybe_value->ToObject(&value)) return maybe_value;
ASSERT(!value->IsTheHole());
uint32_t key =
ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y);
if (ElementsAccessorSubclass::HasElementImpl(
- backing_store, key, holder, receiver)) {
+ receiver, holder, key, backing_store)) {
MaybeObject* maybe_value =
- ElementsAccessorSubclass::GetImpl(backing_store, key,
- holder, receiver);
+ ElementsAccessorSubclass::GetImpl(receiver, holder,
+ key, backing_store);
Object* value;
if (!maybe_value->ToObject(&value)) return maybe_value;
if (!value->IsTheHole() && !HasKey(to, value)) {
BackingStoreClass::cast(backing_store));
}
- static bool HasElementImpl(BackingStoreClass* backing_store,
- uint32_t key,
- JSObject* holder,
- Object* receiver) {
- MaybeObject* element =
- ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver);
- return !element->IsTheHole();
- }
-
- virtual bool HasElement(FixedArrayBase* backing_store,
- uint32_t key,
- JSObject* holder,
- Object* receiver) {
- return ElementsAccessorSubclass::HasElementImpl(
- BackingStoreClass::cast(backing_store), key, holder, receiver);
- }
-
static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store,
uint32_t index) {
return index;
return obj->GetHeap()->true_value();
}
- static bool HasElementImpl(FixedDoubleArray* backing_store,
- uint32_t key,
+ static bool HasElementImpl(Object* receiver,
JSObject* holder,
- Object* receiver) {
+ uint32_t key,
+ FixedDoubleArray* backing_store) {
return !backing_store->is_the_hole(key);
}
};
friend class ElementsAccessorBase<ExternalElementsAccessorSubclass,
ExternalArray>;
- static MaybeObject* GetImpl(ExternalArray* backing_store,
- uint32_t key,
+ static MaybeObject* GetImpl(Object* receiver,
JSObject* obj,
- Object* receiver) {
+ uint32_t key,
+ ExternalArray* backing_store) {
return
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store)
? backing_store->get(key)
: backing_store->GetHeap()->undefined_value();
}
- static MaybeObject* SetLengthImpl(ExternalArray* backing_store,
- JSObject* obj,
- Object* length) {
+ static MaybeObject* SetLengthImpl(JSObject* obj,
+ Object* length,
+ ExternalArray* backing_store) {
// External arrays do not support changing their length.
UNREACHABLE();
return obj;
return obj->GetHeap()->true_value();
}
- static bool HasElementImpl(ExternalArray* backing_store,
- uint32_t key,
+ static bool HasElementImpl(Object* receiver,
JSObject* holder,
- Object* receiver) {
+ uint32_t key,
+ ExternalArray* backing_store) {
uint32_t capacity =
ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store);
return key < capacity;
return DeleteCommon(obj, key, mode);
}
- static MaybeObject* GetImpl(SeededNumberDictionary* backing_store,
- uint32_t key,
+ static MaybeObject* GetImpl(Object* receiver,
JSObject* obj,
- Object* receiver) {
+ uint32_t key,
+ SeededNumberDictionary* backing_store) {
int entry = backing_store->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
Object* element = backing_store->ValueAt(entry);
return obj->GetHeap()->the_hole_value();
}
- static bool HasElementImpl(SeededNumberDictionary* backing_store,
- uint32_t key,
+ static bool HasElementImpl(Object* receiver,
JSObject* holder,
- Object* receiver) {
+ uint32_t key,
+ SeededNumberDictionary* backing_store) {
return backing_store->FindEntry(key) !=
SeededNumberDictionary::kNotFound;
}
friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor,
FixedArray>;
- static MaybeObject* GetImpl(FixedArray* parameter_map,
- uint32_t key,
+ static MaybeObject* GetImpl(Object* receiver,
JSObject* obj,
- Object* receiver) {
+ uint32_t key,
+ FixedArray* parameter_map) {
Object* probe = GetParameterMapArg(obj, parameter_map, key);
if (!probe->IsTheHole()) {
Context* context = Context::cast(parameter_map->get(0));
// Object is not mapped, defer to the arguments.
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get(
- arguments, key, obj, receiver);
+ receiver, obj, key, arguments);
Object* result;
if (!maybe_result->ToObject(&result)) return maybe_result;
// Elements of the arguments object in slow mode might be slow aliases.
}
}
- static MaybeObject* SetLengthImpl(FixedArray* parameter_map,
- JSObject* obj,
- Object* length) {
+ static MaybeObject* SetLengthImpl(JSObject* obj,
+ Object* length,
+ FixedArray* parameter_map) {
// TODO(mstarzinger): This was never implemented but will be used once we
// correctly implement [[DefineOwnProperty]] on arrays.
UNIMPLEMENTED();
return index;
}
- static bool HasElementImpl(FixedArray* parameter_map,
- uint32_t key,
+ static bool HasElementImpl(Object* receiver,
JSObject* holder,
- Object* receiver) {
+ uint32_t key,
+ FixedArray* parameter_map) {
Object* probe = GetParameterMapArg(holder, parameter_map, key);
if (!probe->IsTheHole()) {
return true;
} else {
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
- return !accessor->Get(arguments, key, holder, receiver)->IsTheHole();
+ return !accessor->Get(receiver, holder, key, arguments)->IsTheHole();
}
}
template <typename ElementsAccessorSubclass, typename BackingStoreClass>
MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>::
- SetLengthImpl(BackingStoreClass* backing_store,
- JSObject* obj,
- Object* length) {
+ SetLengthImpl(JSObject* obj,
+ Object* length,
+ BackingStoreClass* backing_store) {
JSArray* array = JSArray::cast(obj);
// Fast case: The new length fits into a Smi.
virtual const char* name() const { return name_; }
- virtual MaybeObject* Get(FixedArrayBase* backing_store,
- uint32_t key,
+ // Returns true if a holder contains an element with the specified key
+ // without iterating up the prototype chain. The caller can optionally pass
+ // in the backing store to use for the check, which must be compatible with
+ // the ElementsKind of the ElementsAccessor. If backing_store is NULL, the
+ // holder->elements() is used as the backing store.
+ virtual bool HasElement(Object* receiver,
+ JSObject* holder,
+ uint32_t key,
+ FixedArrayBase* backing_store = NULL) = 0;
+
+ // Returns the element with the specified key or undefined if there is no such
+ // element. This method doesn't iterate up the prototype chain. The caller
+ // can optionally pass in the backing store to use for the check, which must
+ // be compatible with the ElementsKind of the ElementsAccessor. If
+ // backing_store is NULL, the holder->elements() is used as the backing store.
+ virtual MaybeObject* Get(Object* receiver,
JSObject* holder,
- Object* receiver) = 0;
+ uint32_t key,
+ FixedArrayBase* backing_store = NULL) = 0;
// Modifies the length data property as specified for JSArrays and resizes the
// underlying backing store accordingly. The method honors the semantics of
// changing array sizes as defined in EcmaScript 5.1 15.4.5.2, i.e. array that
// have non-deletable elements can only be shrunk to the size of highest
// element that is non-deletable.
- virtual MaybeObject* SetLength(JSObject* holder,
+ virtual MaybeObject* SetLength(JSArray* holder,
Object* new_length) = 0;
// Modifies both the length and capacity of a JSArray, resizing the underlying
int capacity,
int length) = 0;
+ // Deletes an element in an object, returning a new elements backing store.
virtual MaybeObject* Delete(JSObject* holder,
uint32_t key,
JSReceiver::DeleteMode mode) = 0;
- virtual bool HasElement(FixedArrayBase* backing_store,
- uint32_t key,
- JSObject* holder,
- Object* receiver) = 0;
-
- virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from,
- FixedArray* to,
+ virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
JSObject* holder,
- Object* receiver) = 0;
+ FixedArray* to,
+ FixedArrayBase* from = NULL) = 0;
// Returns a shared ElementsAccessor for the specified ElementsKind.
static ElementsAccessor* ForKind(ElementsKind elements_kind) {
if (js_object->elements() != heap->empty_fixed_array()) {
MaybeObject* result = js_object->GetElementsAccessor()->Get(
- js_object->elements(),
- index,
- js_object,
- receiver);
+ receiver, js_object, index);
if (result != heap->the_hole_value()) return result;
}
}
MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_result =
- accessor->AddElementsToFixedArray(array->elements(), this, array, array);
+ accessor->AddElementsToFixedArray(array, array, this);
FixedArray* result;
if (!maybe_result->To<FixedArray>(&result)) return maybe_result;
#ifdef DEBUG
MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
ElementsAccessor* accessor = ElementsAccessor::ForArray(other);
MaybeObject* maybe_result =
- accessor->AddElementsToFixedArray(other, this, NULL, NULL);
+ accessor->AddElementsToFixedArray(NULL, NULL, this, other);
FixedArray* result;
if (!maybe_result->To<FixedArray>(&result)) return maybe_result;
#ifdef DEBUG
}
if (holder_handle->GetElementsAccessor()->HasElement(
- holder_handle->elements(), index, *holder_handle, *receiver_handle)) {
+ *receiver_handle, *holder_handle, index)) {
return true;
}
}
ElementsAccessor* accessor = GetElementsAccessor();
- if (accessor->HasElement(elements(), index, this, receiver)) {
+ if (accessor->HasElement(receiver, this, index)) {
return true;
}
Heap* heap = holder_handle->GetHeap();
ElementsAccessor* handler = holder_handle->GetElementsAccessor();
- MaybeObject* raw_result = handler->Get(holder_handle->elements(),
- index,
+ MaybeObject* raw_result = handler->Get(*this_handle,
*holder_handle,
- *this_handle);
+ index);
if (raw_result != heap->the_hole_value()) return raw_result;
RETURN_IF_SCHEDULED_EXCEPTION(isolate);