size_t v8::TypedArray::Length() {
i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
- return static_cast<size_t>(obj->length()->Number());
+ return static_cast<size_t>(obj->length_value());
}
if (!IS_UNDEFINED(current) || key in array) {
var new_key = key - del_count + num_additional_args;
new_array[new_key] = current;
- if (new_key > 0xffffffff) {
+ if (new_key > 0xfffffffe) {
big_indices = big_indices || new InternalArray();
big_indices.push(new_key);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
- int len = Smi::cast(array->length())->value();
+ uint32_t len = static_cast<uint32_t>(Smi::cast(array->length())->value());
if (len == 0) return isolate->heap()->undefined_value();
if (JSArray::HasReadOnlyLength(array)) {
}
ElementsAccessor* accessor = array->GetElementsAccessor();
- int new_length = len - 1;
- Handle<Object> element =
- accessor->Get(array, array, new_length, elms_obj).ToHandleChecked();
- if (element->IsTheHole()) {
- return CallJsBuiltin(isolate, "$arrayPop", args);
- }
+ uint32_t new_length = len - 1;
+ Handle<Object> element;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, element, Object::GetElement(isolate, array, new_length));
+
RETURN_FAILURE_ON_EXCEPTION(
isolate,
accessor->SetLength(array, handle(Smi::FromInt(new_length), isolate)));
}
// Get first element
- ElementsAccessor* accessor = array->GetElementsAccessor();
- Handle<Object> first =
- accessor->Get(array, array, 0, elms_obj).ToHandleChecked();
- if (first->IsTheHole()) {
- return CallJsBuiltin(isolate, "$arrayShift", args);
- }
+ Handle<Object> first;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, first,
+ Object::GetElement(isolate, array, 0));
if (heap->CanMoveObjectStart(*elms_obj)) {
array->set_elements(heap->LeftTrimFixedArray(*elms_obj, 1));
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
// Check if we can avoid the bounds check.
- if (key_type->Min() >= 0 &&
- key_type->Max() < array->length()->Number()) {
+ if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
Node* load = graph()->NewNode(
simplified()->LoadElement(
AccessBuilder::ForTypedArrayElement(array->type(), true)),
value = graph()->NewNode(simplified()->NumberToUint32(), value);
}
// Check if we can avoid the bounds check.
- if (key_type->Min() >= 0 &&
- key_type->Max() < array->length()->Number()) {
+ if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
node->set_op(simplified()->StoreElement(
AccessBuilder::ForTypedArrayElement(array->type(), true)));
node->ReplaceInput(0, buffer);
static bool HasElementImpl(Handle<JSObject> holder, uint32_t key,
Handle<FixedArrayBase> backing_store) {
- return ElementsAccessorSubclass::GetAttributesImpl(holder, key,
- backing_store) != ABSENT;
+ return ElementsAccessorSubclass::GetAttributesImpl(
+ *holder, key, *backing_store) != ABSENT;
}
virtual bool HasElement(Handle<JSObject> holder, uint32_t key,
return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store);
}
- MUST_USE_RESULT virtual MaybeHandle<Object> Get(
- Handle<Object> receiver, Handle<JSObject> holder, uint32_t key,
- Handle<FixedArrayBase> backing_store) final {
+ virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t key,
+ Handle<FixedArrayBase> backing_store) final {
if (!IsExternalArrayElementsKind(ElementsTraits::Kind) &&
FLAG_trace_js_array_abuse) {
CheckArrayAbuse(holder, "elements read", key);
CheckArrayAbuse(holder, "external elements read", key);
}
- return ElementsAccessorSubclass::GetImpl(
- receiver, holder, key, backing_store);
+ return ElementsAccessorSubclass::GetImpl(holder, key, backing_store);
}
- MUST_USE_RESULT static MaybeHandle<Object> GetImpl(
- Handle<Object> receiver,
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> backing_store) {
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
+ Handle<FixedArrayBase> backing_store) {
if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) {
return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
} else {
}
}
- MUST_USE_RESULT virtual PropertyAttributes GetAttributes(
- Handle<JSObject> holder, uint32_t key,
- Handle<FixedArrayBase> backing_store) final {
+ virtual PropertyAttributes GetAttributes(
+ JSObject* holder, uint32_t key, FixedArrayBase* backing_store) final {
return ElementsAccessorSubclass::GetAttributesImpl(holder, key,
backing_store);
}
- MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> backing_store) {
- if (key >=
- ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) {
+ static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
+ FixedArrayBase* backing_store) {
+ if (key >= ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) {
return ABSENT;
}
- return
- Handle<BackingStore>::cast(backing_store)->is_the_hole(key)
- ? ABSENT : NONE;
+ return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE;
}
- MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair(
+ virtual MaybeHandle<AccessorPair> GetAccessorPair(
Handle<JSObject> holder, uint32_t key,
Handle<FixedArrayBase> backing_store) final {
return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key,
backing_store);
}
- MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl(
- Handle<JSObject> obj,
- uint32_t key,
+ static MaybeHandle<AccessorPair> GetAccessorPairImpl(
+ Handle<JSObject> obj, uint32_t key,
Handle<FixedArrayBase> backing_store) {
return MaybeHandle<AccessorPair>();
}
from, from_start, *to, from_kind, to_start, packed_size, copy_size);
}
- virtual MaybeHandle<FixedArray> AddElementsToFixedArray(
+ virtual Handle<FixedArray> AddElementsToFixedArray(
Handle<JSObject> receiver, Handle<FixedArray> to,
FixedArray::KeyFilter filter) final {
Handle<FixedArrayBase> from(receiver->elements());
// Compute how many elements are not in other.
uint32_t extra = 0;
for (uint32_t y = 0; y < len1; y++) {
- uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y);
- if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) {
- Handle<Object> value;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, value,
- ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from),
- FixedArray);
+ if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) {
+ uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y);
+ Handle<Object> value =
+ ElementsAccessorSubclass::GetImpl(receiver, key, from);
DCHECK(!value->IsTheHole());
+ DCHECK(!value->IsAccessorPair());
+ DCHECK(!value->IsExecutableAccessorInfo());
if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
continue;
}
// Fill in the extra values.
uint32_t index = 0;
for (uint32_t y = 0; y < len1; y++) {
- uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y);
- if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) {
- Handle<Object> value;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, value,
- ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from),
- FixedArray);
+ if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) {
+ uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y);
+ Handle<Object> value =
+ ElementsAccessorSubclass::GetImpl(receiver, key, from);
+ DCHECK(!value->IsAccessorPair());
+ DCHECK(!value->IsExecutableAccessorInfo());
if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
continue;
}
return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
}
+ static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) {
+ return true;
+ }
+
+ virtual bool HasIndex(FixedArrayBase* backing_store, uint32_t index) final {
+ return ElementsAccessorSubclass::HasIndexImpl(backing_store, index);
+ }
+
static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store,
uint32_t index) {
return index;
return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key);
}
+ static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) {
+ return !BackingStore::cast(backing_store)->is_the_hole(index);
+ }
+
static void ValidateContents(Handle<JSObject> holder, int length) {
#if DEBUG
Isolate* isolate = holder->GetIsolate();
friend class ElementsAccessorBase<AccessorClass,
ElementsKindTraits<Kind> >;
- MUST_USE_RESULT static MaybeHandle<Object> GetImpl(
- Handle<Object> receiver,
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> backing_store) {
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
+ Handle<FixedArrayBase> backing_store) {
if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) {
return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
} else {
}
}
- MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> backing_store) {
- return key < AccessorClass::GetCapacityImpl(*obj, *backing_store) ? NONE
- : ABSENT;
+ static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
+ FixedArrayBase* backing_store) {
+ return key < AccessorClass::GetCapacityImpl(obj, backing_store) ? NONE
+ : ABSENT;
}
MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
return DeleteCommon(obj, key, language_mode);
}
- MUST_USE_RESULT static MaybeHandle<Object> GetImpl(
- Handle<Object> receiver,
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> store) {
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
+ Handle<FixedArrayBase> store) {
Handle<SeededNumberDictionary> backing_store =
Handle<SeededNumberDictionary>::cast(store);
Isolate* isolate = backing_store->GetIsolate();
int entry = backing_store->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
- Handle<Object> element(backing_store->ValueAt(entry), isolate);
- PropertyDetails details = backing_store->DetailsAt(entry);
- if (details.type() == ACCESSOR_CONSTANT) {
- return JSObject::GetElementWithCallback(
- obj, receiver, element, key, obj);
- } else {
- return element;
- }
+ return handle(backing_store->ValueAt(entry), isolate);
}
return isolate->factory()->the_hole_value();
}
- MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> backing_store) {
- Handle<SeededNumberDictionary> dictionary =
- Handle<SeededNumberDictionary>::cast(backing_store);
+ static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
+ FixedArrayBase* backing_store) {
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(backing_store);
int entry = dictionary->FindEntry(key);
if (entry != SeededNumberDictionary::kNotFound) {
return dictionary->DetailsAt(entry).attributes();
return ABSENT;
}
- MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl(
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> store) {
+ static MaybeHandle<AccessorPair> GetAccessorPairImpl(
+ Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) {
Handle<SeededNumberDictionary> backing_store =
Handle<SeededNumberDictionary>::cast(store);
int entry = backing_store->FindEntry(key);
return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound;
}
+ static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) {
+ DisallowHeapAllocation no_gc;
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
+ Object* key = dict->KeyAt(index);
+ return !key->IsTheHole();
+ }
+
static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) {
DisallowHeapAllocation no_gc;
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
SloppyArgumentsElementsAccessor,
ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
- MUST_USE_RESULT static MaybeHandle<Object> GetImpl(
- Handle<Object> receiver,
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> parameters) {
+ static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
+ Handle<FixedArrayBase> parameters) {
Isolate* isolate = obj->GetIsolate();
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
- Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
+ Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
if (!probe->IsTheHole()) {
DisallowHeapAllocation no_gc;
Context* context = Context::cast(parameter_map->get(0));
// Object is not mapped, defer to the arguments.
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
isolate);
- Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, result,
- ElementsAccessor::ForArray(arguments)->Get(
- receiver, obj, key, arguments),
- Object);
+ Handle<Object> result =
+ ElementsAccessor::ForArray(arguments)->Get(obj, key, arguments);
// Elements of the arguments object in slow mode might be slow aliases.
if (result->IsAliasedArgumentsEntry()) {
DisallowHeapAllocation no_gc;
}
}
- MUST_USE_RESULT static PropertyAttributes GetAttributesImpl(
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> backing_store) {
- Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store);
- Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
+ static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
+ FixedArrayBase* backing_store) {
+ FixedArray* parameter_map = FixedArray::cast(backing_store);
+ Object* probe = GetParameterMapArg(parameter_map, key);
if (!probe->IsTheHole()) {
return NONE;
} else {
// If not aliased, check the arguments.
- Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
return ElementsAccessor::ForArray(arguments)
->GetAttributes(obj, key, arguments);
}
}
- MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl(
- Handle<JSObject> obj,
- uint32_t key,
- Handle<FixedArrayBase> parameters) {
+ static MaybeHandle<AccessorPair> GetAccessorPairImpl(
+ Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
- Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
+ Handle<Object> probe(GetParameterMapArg(*parameter_map, key),
+ obj->GetIsolate());
if (!probe->IsTheHole()) {
return MaybeHandle<AccessorPair>();
} else {
Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final {
Isolate* isolate = obj->GetIsolate();
Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
- Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
+ Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
if (!probe->IsTheHole()) {
// TODO(kmillikin): We could check if this was the last aliased
// parameter, and revert to normal elements in that case. That
FixedArrayBase* backing_store) {
FixedArray* parameter_map = FixedArray::cast(backing_store);
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
- return Max(static_cast<uint32_t>(parameter_map->length() - 2),
- ForArray(arguments)->GetCapacity(holder, arguments));
+ return parameter_map->length() - 2 +
+ ForArray(arguments)->GetCapacity(holder, arguments);
}
- static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, uint32_t index) {
- return index;
+ static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) {
+ FixedArray* parameter_map = FixedArray::cast(parameters);
+ uint32_t length = parameter_map->length() - 2;
+ if (index < length) {
+ return !GetParameterMapArg(parameter_map, index)->IsTheHole();
+ }
+
+ FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
+ return ForArray(arguments)->HasIndex(arguments, index - length);
}
- static uint32_t GetIndexForKeyImpl(FixedArrayBase* dict, uint32_t key) {
- return key;
+ static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters,
+ uint32_t index) {
+ FixedArray* parameter_map = FixedArray::cast(parameters);
+ uint32_t length = parameter_map->length() - 2;
+ if (index < length) return index;
+
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+ return ForArray(arguments)->GetKeyForIndex(arguments, index - length);
}
- static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
- uint32_t index) {
- return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
+ static uint32_t GetIndexForKeyImpl(FixedArrayBase* parameters, uint32_t key) {
+ FixedArray* parameter_map = FixedArray::cast(parameters);
+ Object* probe = GetParameterMapArg(parameter_map, key);
+ if (!probe->IsTheHole()) return key;
+
+ uint32_t length = parameter_map->length() - 2;
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+ return length +
+ ElementsAccessor::ForArray(arguments)
+ ->GetIndexForKey(arguments, key);
}
+ static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
+ uint32_t index) {
+ FixedArray* parameter_map = FixedArray::cast(parameters);
+ uint32_t length = parameter_map->length() - 2;
+ if (index < length) {
+ return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
+ }
+ index -= length;
+ FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
+ return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index);
+ }
private:
- static Handle<Object> GetParameterMapArg(Handle<JSObject> holder,
- Handle<FixedArray> parameter_map,
- uint32_t key) {
- Isolate* isolate = holder->GetIsolate();
- uint32_t length = holder->IsJSArray()
- ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value()
- : parameter_map->length();
- return key < (length - 2)
- ? handle(parameter_map->get(key + 2), isolate)
- : Handle<Object>::cast(isolate->factory()->the_hole_value());
+ static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
+ uint32_t length = parameter_map->length() - 2;
+ return key < length
+ ? parameter_map->get(key + 2)
+ : Object::cast(parameter_map->GetHeap()->the_hole_value());
}
};
// to slow elements is needed for other reasons.
if (length->IsNumber()) {
uint32_t value;
- if (length->ToArrayIndex(&value)) {
+ if (length->ToArrayLength(&value)) {
Handle<SeededNumberDictionary> dictionary =
JSObject::NormalizeElements(array);
DCHECK(!dictionary.is_null());
// 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.
- MUST_USE_RESULT virtual MaybeHandle<Object> Get(
- Handle<Object> receiver,
- Handle<JSObject> holder,
- uint32_t key,
- Handle<FixedArrayBase> backing_store) = 0;
+ virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t key,
+ Handle<FixedArrayBase> backing_store) = 0;
- MUST_USE_RESULT inline MaybeHandle<Object> Get(
- Handle<Object> receiver,
- Handle<JSObject> holder,
- uint32_t key) {
- return Get(receiver, holder, key, handle(holder->elements()));
+ inline Handle<Object> Get(Handle<JSObject> holder, uint32_t key) {
+ return Get(holder, key, handle(holder->elements()));
}
// Returns an element's attributes, or ABSENT if there is no such
// 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.
- MUST_USE_RESULT virtual PropertyAttributes GetAttributes(
- Handle<JSObject> holder,
- uint32_t key,
- Handle<FixedArrayBase> backing_store) = 0;
+ virtual PropertyAttributes GetAttributes(JSObject* holder, uint32_t key,
+ FixedArrayBase* backing_store) = 0;
- MUST_USE_RESULT inline PropertyAttributes GetAttributes(
- Handle<JSObject> holder,
- uint32_t key) {
- return GetAttributes(holder, key, handle(holder->elements()));
+ inline PropertyAttributes GetAttributes(Handle<JSObject> holder,
+ uint32_t key) {
+ return GetAttributes(*holder, key, holder->elements());
}
// Returns an element's accessors, or NULL if the element does not exist or
// 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.
- MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair(
- Handle<JSObject> holder,
- uint32_t key,
+ virtual MaybeHandle<AccessorPair> GetAccessorPair(
+ Handle<JSObject> holder, uint32_t key,
Handle<FixedArrayBase> backing_store) = 0;
- MUST_USE_RESULT inline MaybeHandle<AccessorPair> GetAccessorPair(
- Handle<JSObject> holder,
- uint32_t key) {
+ inline MaybeHandle<AccessorPair> GetAccessorPair(Handle<JSObject> holder,
+ uint32_t key) {
return GetAccessorPair(holder, key, handle(holder->elements()));
}
*from_holder, 0, from_kind, to, 0, kCopyToEndAndInitializeToHole);
}
- MUST_USE_RESULT virtual MaybeHandle<FixedArray> AddElementsToFixedArray(
+ virtual Handle<FixedArray> AddElementsToFixedArray(
Handle<JSObject> receiver, Handle<FixedArray> to,
FixedArray::KeyFilter filter) = 0;
uint32_t key) = 0;
virtual PropertyDetails GetDetails(FixedArrayBase* backing_store,
uint32_t index) = 0;
+ virtual bool HasIndex(FixedArrayBase* backing_store, uint32_t key) = 0;
private:
static ElementsAccessor** elements_accessors_;
RUNTIME_FUNCTION(LoadElementWithInterceptor) {
+ // TODO(verwaest): This should probably get the holder and receiver as input.
HandleScope scope(isolate);
Handle<JSObject> receiver = args.at<JSObject>(0);
DCHECK(args.smi_at(1) >= 0);
uint32_t index = args.smi_at(1);
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSObject::GetElementWithInterceptor(receiver, receiver, index, true));
+ isolate, result, Object::GetElement(isolate, receiver, index));
return *result;
}
} else {
do {
int d = c0_ - '0';
- if (index > 429496729U - ((d > 5) ? 1 : 0)) break;
+ if (index > 429496729U - ((d + 3) >> 3)) break;
index = (index * 10) + d;
Advance();
} while (IsDecimalDigit(c0_));
Result stack_push = StackPush(object);
if (stack_push != SUCCESS) return stack_push;
uint32_t length = 0;
- CHECK(object->length()->ToArrayIndex(&length));
+ CHECK(object->length()->ToArrayLength(&length));
builder_.AppendCharacter('[');
switch (object->GetElementsKind()) {
case FAST_SMI_ELEMENTS: {
// Fall through.
case INTERCEPTOR:
if (IsElement()) {
+ // TODO(verwaest): Optimize.
JSObject* js_object = JSObject::cast(holder);
ElementsAccessor* accessor = js_object->GetElementsAccessor();
FixedArrayBase* backing_store = js_object->elements();
number_ = accessor->GetIndexForKey(backing_store, index_);
if (number_ == kMaxUInt32) return NOT_FOUND;
+ if (accessor->GetAttributes(js_object, index_, backing_store) ==
+ ABSENT) {
+ return NOT_FOUND;
+ }
property_details_ = accessor->GetDetails(backing_store, number_);
} else if (holder->IsGlobalObject()) {
GlobalDictionary* dict = JSObject::cast(holder)->global_dictionary();
bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
+ return InternalHolderIsReceiverOrHiddenPrototype();
+}
+
+bool LookupIterator::InternalHolderIsReceiverOrHiddenPrototype() const {
// Optimization that only works if configuration_ is not mutable.
if (!check_prototype_chain()) return true;
DisallowHeapAllocation no_gc;
Handle<Object> LookupIterator::FetchValue() const {
Object* result = NULL;
Handle<JSObject> holder = GetHolder<JSObject>();
- if (holder_map_->IsGlobalObjectMap()) {
+ if (IsElement()) {
+ // TODO(verwaest): Optimize.
+ ElementsAccessor* accessor = holder->GetElementsAccessor();
+ return accessor->Get(holder, index_);
+ } else if (holder_map_->IsGlobalObjectMap()) {
result = holder->global_dictionary()->ValueAt(number_);
DCHECK(result->IsPropertyCell());
result = PropertyCell::cast(result)->value();
DCHECK(has_property_);
DCHECK(!holder_map_->is_dictionary_map());
DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type());
+ DCHECK(!IsElement());
return descriptor_number();
}
DCHECK(has_property_);
DCHECK(!holder_map_->is_dictionary_map());
DCHECK_EQ(v8::internal::DATA, property_details_.type());
+ DCHECK(!IsElement());
int index =
holder_map_->instance_descriptors()->GetFieldIndex(descriptor_number());
bool is_double = representation().IsDouble();
Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
+ DCHECK(!IsElement());
Handle<JSObject> holder = GetHolder<JSObject>();
Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
Object* value = global->global_dictionary()->ValueAt(dictionary_entry());
void LookupIterator::WriteDataValue(Handle<Object> value) {
DCHECK_EQ(DATA, state_);
+ DCHECK(!IsElement());
Handle<JSObject> holder = GetHolder<JSObject>();
if (holder->IsGlobalObject()) {
Handle<GlobalDictionary> property_dictionary =
// Currently typed arrays are the only such objects.
if (!holder->IsJSTypedArray()) return false;
if (exotic_index_state_ == ExoticIndexState::kExotic) return true;
+ if (!InternalHolderIsReceiverOrHiddenPrototype()) {
+ exotic_index_state_ = ExoticIndexState::kNotExotic;
+ return false;
+ }
DCHECK(exotic_index_state_ == ExoticIndexState::kUninitialized);
bool result = false;
// Compute and cache result.
- if (name()->IsString()) {
+ if (IsElement()) {
+ result = index_ >= JSTypedArray::cast(holder)->length_value();
+ } else if (name()->IsString()) {
Handle<String> name_string = Handle<String>::cast(name());
if (name_string->length() != 0) {
result = IsSpecialIndex(isolate_->unicode_cache(), *name_string);
Handle<InterceptorInfo> LookupIterator::GetInterceptor() const {
DCHECK_EQ(INTERCEPTOR, state_);
- Handle<JSObject> js_holder = Handle<JSObject>::cast(holder_);
- if (IsElement()) return handle(js_holder->GetIndexedInterceptor(), isolate_);
- return handle(js_holder->GetNamedInterceptor(), isolate_);
+ return handle(GetInterceptor(JSObject::cast(*holder_)), isolate_);
+}
+
+
+InterceptorInfo* LookupIterator::GetInterceptor(JSObject* holder) const {
+ if (IsElement()) return holder->GetIndexedInterceptor();
+ return holder->GetNamedInterceptor();
}
bool LookupIterator::SkipInterceptor(JSObject* holder) {
- auto info = holder->GetNamedInterceptor();
+ auto info = GetInterceptor(holder);
// TODO(dcarney): check for symbol/can_intercept_symbols here as well.
if (info->non_masking()) {
switch (interceptor_state_) {
Configuration configuration = PROTOTYPE_CHAIN)
: configuration_(configuration),
state_(NOT_FOUND),
- exotic_index_state_(ExoticIndexState::kNotExotic),
+ exotic_index_state_(ExoticIndexState::kUninitialized),
interceptor_state_(InterceptorState::kUninitialized),
property_details_(PropertyDetails::Empty()),
isolate_(isolate),
Configuration configuration = PROTOTYPE_CHAIN)
: configuration_(configuration),
state_(NOT_FOUND),
- exotic_index_state_(ExoticIndexState::kNotExotic),
+ exotic_index_state_(ExoticIndexState::kUninitialized),
interceptor_state_(InterceptorState::kUninitialized),
property_details_(PropertyDetails::Empty()),
isolate_(isolate),
void ReloadPropertyInformation();
bool SkipInterceptor(JSObject* holder);
bool HasInterceptor(Map* map) const;
+ bool InternalHolderIsReceiverOrHiddenPrototype() const;
+ InterceptorInfo* GetInterceptor(JSObject* holder) const;
bool IsBootstrapping() const;
MaybeHandle<Object> Object::GetElement(Isolate* isolate,
Handle<Object> object,
uint32_t index) {
- // GetElement can trigger a getter which can cause allocation.
- // This was not always the case. This DCHECK is here to catch
- // leftover incorrect uses.
- DCHECK(AllowHeapAllocation::IsAllowed());
- return Object::GetElementWithReceiver(isolate, object, object, index);
+ LookupIterator it(isolate, object, index);
+ return GetProperty(&it);
}
}
-MaybeHandle<Object> JSProxy::GetElementWithHandler(Handle<JSProxy> proxy,
- Handle<Object> receiver,
- uint32_t index) {
- return GetPropertyWithHandler(
- proxy, receiver, proxy->GetIsolate()->factory()->Uint32ToString(index));
-}
-
-
MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy,
Handle<JSReceiver> receiver,
uint32_t index,
}
-bool Object::ToArrayIndex(uint32_t* index) {
+bool Object::ToArrayLength(uint32_t* index) {
if (IsSmi()) {
int value = Smi::cast(this)->value();
if (value < 0) return false;
}
+bool Object::ToArrayIndex(uint32_t* index) {
+ return ToArrayLength(index) && *index != kMaxUInt32;
+}
+
+
bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
if (!this->IsJSValue()) return false;
}
+uint32_t JSTypedArray::length_value() const {
+ if (WasNeutered()) return 0;
+ uint32_t index = 0;
+ CHECK(Object::cast(READ_FIELD(this, kLengthOffset))->ToArrayLength(&index));
+ return index;
+}
+
+
void JSTypedArray::set_length(Object* value, WriteBarrierMode mode) {
WRITE_FIELD(this, kLengthOffset, value);
CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kLengthOffset, value, mode);
return false;
}
}
- if (array_index_ > 429496729U - ((d + 2) >> 3)) {
+ if (array_index_ > 429496729U - ((d + 3) >> 3)) {
is_array_index_ = false;
return false;
}
}
-MaybeHandle<Object> JSObject::GetElementWithFailedAccessCheck(
- Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
- uint32_t index) {
- Handle<JSObject> holder = object;
- PrototypeIterator::WhereToStart where_to_start =
- PrototypeIterator::START_AT_RECEIVER;
- while (true) {
- auto all_can_read_holder =
- FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
- if (!all_can_read_holder.ToHandle(&holder)) break;
- auto result =
- JSObject::GetElementWithInterceptor(holder, receiver, index, false);
- if (isolate->has_scheduled_exception()) break;
- if (!result.is_null()) return result;
- where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
- }
- isolate->ReportFailedAccessCheck(object);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return isolate->factory()->undefined_value();
-}
-
-
Maybe<PropertyAttributes> JSObject::GetElementAttributesWithFailedAccessCheck(
Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
uint32_t index) {
}
-MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate,
- Handle<Object> object,
- Handle<Object> receiver,
- uint32_t index) {
- DCHECK(!object->IsUndefined());
-
- // Iterate up the prototype chain until an element is found or the null
- // prototype is encountered.
- for (PrototypeIterator iter(isolate, object,
- object->IsJSProxy() || object->IsJSObject()
- ? PrototypeIterator::START_AT_RECEIVER
- : PrototypeIterator::START_AT_PROTOTYPE);
- !iter.IsAtEnd(); iter.Advance()) {
- if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
- return JSProxy::GetElementWithHandler(
- Handle<JSProxy>::cast(PrototypeIterator::GetCurrent(iter)), receiver,
- index);
- }
-
- // Inline the case for JSObjects. Doing so significantly improves the
- // performance of fetching elements where checking the prototype chain is
- // necessary.
- Handle<JSObject> js_object =
- Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-
- // Check access rights if needed.
- if (js_object->IsAccessCheckNeeded()) {
- if (!isolate->MayAccess(js_object)) {
- return JSObject::GetElementWithFailedAccessCheck(isolate, js_object,
- receiver, index);
- }
- }
-
- if (js_object->HasIndexedInterceptor()) {
- return JSObject::GetElementWithInterceptor(js_object, receiver, index,
- true);
- }
-
- if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
- Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, result,
- js_object->GetElementsAccessor()->Get(receiver, js_object, index),
- Object);
- if (!result->IsTheHole()) return result;
- }
- }
-
- return isolate->factory()->undefined_value();
-}
-
-
MaybeHandle<Object> Object::SetElementWithReceiver(
Isolate* isolate, Handle<Object> object, Handle<Object> receiver,
uint32_t index, Handle<Object> value, LanguageMode language_mode) {
Handle<FixedArray> content, Handle<JSObject> array, KeyFilter filter) {
DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements());
ElementsAccessor* accessor = array->GetElementsAccessor();
- Handle<FixedArray> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- array->GetIsolate(), result,
- accessor->AddElementsToFixedArray(array, content, filter), FixedArray);
+ Handle<FixedArray> result =
+ accessor->AddElementsToFixedArray(array, content, filter);
#ifdef ENABLE_SLOW_DCHECKS
if (FLAG_enable_slow_asserts) {
List<Handle<Object> > old_values;
Handle<Object> old_length_handle(array->length(), isolate);
uint32_t old_length = 0;
- CHECK(old_length_handle->ToArrayIndex(&old_length));
+ CHECK(old_length_handle->ToArrayLength(&old_length));
uint32_t new_length = 0;
- CHECK(new_length_handle->ToArrayIndex(&new_length));
+ CHECK(new_length_handle->ToArrayLength(&new_length));
static const PropertyAttributes kNoAttrFilter = NONE;
int num_elements = array->NumberOfOwnElements(kNoAttrFilter);
array->GetElementsAccessor()->SetLength(array, new_length_handle),
Object);
- CHECK(array->length()->ToArrayIndex(&new_length));
+ CHECK(array->length()->ToArrayLength(&new_length));
if (old_length == new_length) return hresult;
RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object);
}
-MaybeHandle<Object> JSObject::GetElementWithCallback(
- Handle<JSObject> object,
- Handle<Object> receiver,
- Handle<Object> structure,
- uint32_t index,
- Handle<Object> holder) {
- Isolate* isolate = object->GetIsolate();
- DCHECK(!structure->IsForeign());
- // api style callbacks.
- if (structure->IsExecutableAccessorInfo()) {
- Handle<ExecutableAccessorInfo> data =
- Handle<ExecutableAccessorInfo>::cast(structure);
- Object* fun_obj = data->getter();
- v8::AccessorNameGetterCallback call_fun =
- v8::ToCData<v8::AccessorNameGetterCallback>(fun_obj);
- if (call_fun == NULL) return isolate->factory()->undefined_value();
- Handle<JSObject> holder_handle = Handle<JSObject>::cast(holder);
- Handle<String> key = isolate->factory()->Uint32ToString(index);
- LOG(isolate, ApiNamedPropertyAccess("load", *holder_handle, *key));
- PropertyCallbackArguments
- args(isolate, data->data(), *receiver, *holder_handle);
- v8::Handle<v8::Value> result = args.Call(call_fun, v8::Utils::ToLocal(key));
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- if (result.IsEmpty()) return isolate->factory()->undefined_value();
- Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
- result_internal->VerifyApiCallResultType();
- // Rebox handle before return.
- return handle(*result_internal, isolate);
- }
-
- // __defineGetter__ callback
- if (structure->IsAccessorPair()) {
- Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
- isolate);
- if (getter->IsSpecFunction()) {
- // TODO(rossberg): nicer would be to cast to some JSCallable here...
- return GetPropertyWithDefinedGetter(
- receiver, Handle<JSReceiver>::cast(getter));
- }
- // Getter is not a function.
- return isolate->factory()->undefined_value();
- }
-
- UNREACHABLE();
- return MaybeHandle<Object>();
-}
-
-
MaybeHandle<Object> JSObject::SetElementWithCallback(
Handle<Object> object, Handle<Object> structure, uint32_t index,
Handle<Object> value, Handle<JSObject> holder, LanguageMode language_mode) {
bool must_update_array_length = false;
bool introduces_holes = true;
if (object->IsJSArray()) {
- CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length));
+ CHECK(
+ Handle<JSArray>::cast(object)->length()->ToArrayLength(&array_length));
introduces_holes = index > array_length;
if (index >= array_length) {
must_update_array_length = true;
if (object->ShouldConvertToFastElements()) {
uint32_t new_length = 0;
if (object->IsJSArray()) {
- CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&new_length));
+ CHECK(
+ Handle<JSArray>::cast(object)->length()->ToArrayLength(&new_length));
} else {
new_length = dictionary->max_number_key() + 1;
}
bool introduces_holes = true;
uint32_t length = elms_length;
if (object->IsJSArray()) {
- CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length));
+ CHECK(Handle<JSArray>::cast(object)->length()->ToArrayLength(&length));
introduces_holes = index > length;
} else {
introduces_holes = index >= elms_length;
if (object->IsJSArray()) {
// Update the length of the array if needed.
uint32_t array_length = 0;
- CHECK(
- Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length));
+ CHECK(Handle<JSArray>::cast(object)->length()->ToArrayLength(
+ &array_length));
if (index >= array_length) {
Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1));
}
isolate);
uint32_t old_length = 0;
uint32_t new_length = 0;
- CHECK(old_length_handle->ToArrayIndex(&old_length));
- CHECK(new_length_handle->ToArrayIndex(&new_length));
+ CHECK(old_length_handle->ToArrayLength(&old_length));
+ CHECK(new_length_handle->ToArrayLength(&new_length));
RETURN_ON_EXCEPTION(
isolate, BeginPerformSplice(Handle<JSArray>::cast(object)), Object);
// If the array is huge, it's not likely to be defined in a local
// function, so we shouldn't make new instances of it very often.
uint32_t length = 0;
- CHECK(transition_info->length()->ToArrayIndex(&length));
+ CHECK(transition_info->length()->ToArrayLength(&length));
if (length <= kMaximumArrayBytesToPretransition) {
if (FLAG_trace_track_allocation_sites) {
bool is_nested = site->IsNestedSite();
// elements, assume a length of zero.
length = 0;
} else {
- CHECK(raw_length->ToArrayIndex(&length));
+ CHECK(raw_length->ToArrayLength(&length));
}
}
uint32_t index,
Handle<Object> value) {
uint32_t old_len = 0;
- CHECK(array->length()->ToArrayIndex(&old_len));
+ CHECK(array->length()->ToArrayLength(&old_len));
// Check to see if we need to update the length. For now, we make
// sure that the length stays within 32-bits (unsigned).
if (index >= old_len && index != 0xffffffff) {
bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
uint32_t index) {
uint32_t length = 0;
- CHECK(array->length()->ToArrayIndex(&length));
+ CHECK(array->length()->ToArrayLength(&length));
if (length <= index) return HasReadOnlyLength(array);
return false;
}
}
-MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object,
- Handle<Object> receiver,
- uint32_t index,
- bool check_prototype) {
- Isolate* isolate = object->GetIsolate();
-
- // Make sure that the top context does not change when doing
- // callbacks or interceptor calls.
- AssertNoContextChange ncc(isolate);
-
- Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor(), isolate);
- if (!interceptor->getter()->IsUndefined()) {
- v8::IndexedPropertyGetterCallback getter =
- v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
- LOG(isolate,
- ApiIndexedPropertyAccess("interceptor-indexed-get", *object, index));
- PropertyCallbackArguments
- args(isolate, interceptor->data(), *receiver, *object);
- v8::Handle<v8::Value> result = args.Call(getter, index);
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- if (!result.IsEmpty()) {
- Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
- result_internal->VerifyApiCallResultType();
- // Rebox handle before return.
- return handle(*result_internal, isolate);
- }
- }
-
- if (!check_prototype) return MaybeHandle<Object>();
-
- ElementsAccessor* handler = object->GetElementsAccessor();
- Handle<Object> result;
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, result, handler->Get(receiver, object, index),
- Object);
- if (!result->IsTheHole()) return result;
-
- PrototypeIterator iter(isolate, object);
- if (iter.IsAtEnd()) return isolate->factory()->undefined_value();
- return Object::GetElementWithReceiver(
- isolate, PrototypeIterator::GetCurrent(iter), receiver, index);
-}
-
-
bool JSObject::HasDenseElements() {
int capacity = 0;
int used = 0;
// the object should have fast elements.
uint32_t array_size = 0;
if (IsJSArray()) {
- CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size));
+ CHECK(JSArray::cast(this)->length()->ToArrayLength(&array_size));
} else {
array_size = dictionary->max_number_key();
}
Handle<Object> object,
uint32_t index);
- MUST_USE_RESULT static MaybeHandle<Object> GetElementWithReceiver(
- Isolate* isolate,
- Handle<Object> object,
- Handle<Object> receiver,
- uint32_t index);
-
MUST_USE_RESULT static MaybeHandle<Object> SetElementWithReceiver(
Isolate* isolate, Handle<Object> object, Handle<Object> receiver,
uint32_t index, Handle<Object> value, LanguageMode language_mode);
// by ES6 Map and Set.
bool SameValueZero(Object* other);
- // Tries to convert an object to an array index. Returns true and sets
- // the output parameter if it succeeds.
+ // Tries to convert an object to an array length. Returns true and sets the
+ // output parameter if it succeeds.
+ inline bool ToArrayLength(uint32_t* index);
+
+ // Tries to convert an object to an array index. Returns true and sets the
+ // output parameter if it succeeds. Equivalent to ToArrayLength, but does not
+ // allow kMaxUInt32.
inline bool ToArrayIndex(uint32_t* index);
// Returns true if this is a JSValue containing a string and the index is
PropertyAttributes attributes, LanguageMode language_mode,
bool check_prototype = true, SetPropertyMode set_mode = SET_PROPERTY);
- // Returns the index'th element.
- // The undefined object if index is out of bounds.
- MUST_USE_RESULT static MaybeHandle<Object> GetElementWithInterceptor(
- Handle<JSObject> object, Handle<Object> receiver, uint32_t index,
- bool check_prototype);
-
enum SetFastElementsCapacitySmiMode {
kAllowSmiElements,
kForceSmiElements,
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithFailedAccessCheck(
LookupIterator* it);
- MUST_USE_RESULT static MaybeHandle<Object> GetElementWithCallback(
- Handle<JSObject> object,
- Handle<Object> receiver,
- Handle<Object> structure,
- uint32_t index,
- Handle<Object> holder);
-
MUST_USE_RESULT static Maybe<PropertyAttributes>
GetElementAttributeWithInterceptor(Handle<JSObject> object,
Handle<JSReceiver> receiver,
MUST_USE_RESULT static MaybeHandle<Object> SetFastDoubleElement(
Handle<JSObject> object, uint32_t index, Handle<Object> value,
LanguageMode language_mode, bool check_prototype = true);
- MUST_USE_RESULT static MaybeHandle<Object> GetElementWithFailedAccessCheck(
- Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
- uint32_t index);
MUST_USE_RESULT static Maybe<PropertyAttributes>
GetElementAttributesWithFailedAccessCheck(Isolate* isolate,
Handle<JSObject> object,
Handle<JSProxy> proxy,
Handle<Object> receiver,
Handle<Name> name);
- MUST_USE_RESULT static inline MaybeHandle<Object> GetElementWithHandler(
- Handle<JSProxy> proxy,
- Handle<Object> receiver,
- uint32_t index);
// If the handler defines an accessor property with a setter, invoke it.
// If it defines an accessor property without a setter, or a data property
public:
// [length]: length of typed array in elements.
DECL_ACCESSORS(length, Object)
+ inline uint32_t length_value() const;
DECLARE_CAST(JSTypedArray)
break;
}
case SLOPPY_ARGUMENTS_ELEMENTS: {
- ElementsAccessor* accessor = receiver->GetElementsAccessor();
for (uint32_t index = 0; index < length; index++) {
HandleScope loop_scope(isolate);
- if (accessor->HasElement(receiver, index)) {
- Handle<Object> element;
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate, element, accessor->Get(receiver, receiver, index),
- false);
- visitor->visit(index, element);
- }
+ Handle<Object> element;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate, element, Object::GetElement(isolate, receiver, index),
+ false);
+ visitor->visit(index, element);
}
break;
}
Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
+ LookupIterator it(isolate, receiver, index, Handle<JSReceiver>::cast(proto));
Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- Object::GetElementWithReceiver(isolate, proto, receiver, index));
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
return *result;
}
RUNTIME_ASSERT(obj->HasIndexedInterceptor());
CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- JSObject::GetElementWithInterceptor(obj, obj, index, true));
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ Object::GetElement(isolate, obj, index));
return *result;
}
RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
+ size_t length = 0;
if (source->IsJSTypedArray() &&
JSTypedArray::cast(*source)->type() == array_type) {
- length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
+ length_obj = handle(JSTypedArray::cast(*source)->length(), isolate);
+ length = JSTypedArray::cast(*source)->length_value();
+ } else {
+ RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
}
- size_t length = 0;
- RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
(length > (kMaxInt / element_size))) {
#define BUFFER_VIEW_GETTER(Type, getter, accessor) \
RUNTIME_FUNCTION(Runtime_##Type##Get##getter) { \
HandleScope scope(isolate); \
- DCHECK(args.length() == 1); \
+ DCHECK_EQ(1, args.length()); \
CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
return holder->accessor(); \
}
RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
+ DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
return *holder->GetBuffer();
}
Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
size_t offset = 0;
RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
- size_t target_length = NumberToSize(isolate, target->length());
- size_t source_length = NumberToSize(isolate, source->length());
+ size_t target_length = target->length_value();
+ size_t source_length = source->length_value();
size_t target_byte_length = NumberToSize(isolate, target->byte_length());
size_t source_byte_length = NumberToSize(isolate, source->byte_length());
if (offset > target_length || offset + source_length > target_length ||
d = stream->GetNext() - '0';
if (d < 0 || d > 9) return false;
// Check that the new result is below the 32 bit limit.
- if (result > 429496729U - ((d > 5) ? 1 : 0)) return false;
+ if (result > 429496729U - ((d + 3) >> 3)) return false;
result = (result * 10) + d;
}
"k.a = 0;"
"k[5] = 0;"
"k.b = 0;"
- "k[4294967295] = 0;"
+ "k[4294967294] = 0;"
"k.c = 0;"
- "k[4294967296] = 0;"
+ "k[4294967295] = 0;"
"k.d = 0;"
"k[140000] = 0;"
"k.e = 0;"
CHECK(v8_str("10")->Equals(result->Get(v8::Integer::New(isolate, 1))));
CHECK(v8_str("140000")->Equals(result->Get(v8::Integer::New(isolate, 2))));
CHECK(
- v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 3))));
+ v8_str("4294967294")->Equals(result->Get(v8::Integer::New(isolate, 3))));
// Indexed interceptor properties in the order they are returned
// from the enumerator interceptor.
CHECK(v8_str("0")->Equals(result->Get(v8::Integer::New(isolate, 4))));
CHECK(v8_str("b")->Equals(result->Get(v8::Integer::New(isolate, 7))));
CHECK(v8_str("c")->Equals(result->Get(v8::Integer::New(isolate, 8))));
CHECK(
- v8_str("4294967296")->Equals(result->Get(v8::Integer::New(isolate, 9))));
+ v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 9))));
CHECK(v8_str("d")->Equals(result->Get(v8::Integer::New(isolate, 10))));
CHECK(v8_str("e")->Equals(result->Get(v8::Integer::New(isolate, 11))));
CHECK(v8_str("30000000000")
str = v8_str("-42");
index = str->ToArrayIndex();
CHECK(index.IsEmpty());
- str = v8_str("4294967295");
+ str = v8_str("4294967294");
index = str->ToArrayIndex();
CHECK(!index.IsEmpty());
- CHECK_EQ(4294967295.0, index->Uint32Value());
+ CHECK_EQ(4294967294.0, index->Uint32Value());
v8::Handle<v8::Number> num = v8::Number::New(isolate, 1);
index = num->ToArrayIndex();
CHECK(!index.IsEmpty());
proto2[2] = 0;
proto2[3] = 0; // also on the 'proto1' object
proto2.b = 0;
-proto2[4294967295] = 0;
+proto2[4294967294] = 0;
proto2.c = 0;
-proto2[4294967296] = 0;
+proto2[4294967295] = 0;
var proto1 = {};
proto1[5] = 0;
'-23', '300000000000', 'f', 'g', '-4', // named from 'o'
'3', '5', // indexed from 'proto1'
'd', 'e', // named from 'proto1'
- '2', '140000', '4294967295', // indexed from 'proto2'
- 'a', 'b', 'c', '4294967296']; // named from 'proto2'
+ '2', '140000', '4294967294', // indexed from 'proto2'
+ 'a', 'b', 'c', '4294967295']; // named from 'proto2'
var actual = [];
for (var p in o) actual.push(p);
assertArrayEquals(expected, actual);
Object.prototype["7"] = "unreachable";
Object.prototype["-1"] = "unreachable";
Object.prototype["-0"] = "unreachable";
-Object.prototype["4294967296"] = "unreachable";
+Object.prototype["4294967295"] = "unreachable";
var array = new Int32Array(10);
assertEquals(undefined, array["-1"]);
assertEquals(undefined, array["-0"]);
assertEquals(undefined, array["10"]);
- assertEquals(undefined, array["4294967296"]);
+ assertEquals(undefined, array["4294967295"]);
}
assertEquals("unreachable", array.__proto__["-1"]);
assertEquals("unreachable", array.__proto__["-0"]);
assertEquals("unreachable", array.__proto__["10"]);
- assertEquals("unreachable", array.__proto__["4294967296"]);
+ assertEquals("unreachable", array.__proto__["4294967295"]);
}
check();
array["-1"] = "unreachable";
array["-0"] = "unreachable";
array["10"] = "unreachable";
-array["4294967296"] = "unreachable";
+array["4294967295"] = "unreachable";
check();
delete array["-0"];
delete array["-1"];
delete array["10"];
-delete array["4294967296"];
+delete array["4294967295"];
assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "-1"));
assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "-0"));
assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "10"));
-assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "4294967296"));
+assertEquals(undefined, Object.getOwnPropertyDescriptor(array, "4294967295"));
assertEquals(10, Object.keys(array).length);
check();
Object.defineProperty(new Int32Array(), "-1", {'value': 1});
Object.defineProperty(new Int32Array(), "-0", {'value': 1});
Object.defineProperty(new Int32Array(), "-10", {'value': 1});
-Object.defineProperty(new Int32Array(), "4294967296", {'value': 1});
+Object.defineProperty(new Int32Array(), "4294967295", {'value': 1});
check();
assertThrows(function() { a.concat(a); }, RangeError);
var b = [];
-b[pow31 - 2] = 32;
+b[pow31 - 3] = 32;
+b[pow31 - 2] = "out_of_bounds";
var ab = a.concat(b);
assertEquals(2 * pow31 - 1, ab.length);
assertEquals(31, ab[pow31]);
-assertEquals(32, ab[2 * pow31 - 1]);
+assertEquals(32, ab[2 * pow31 - 2]);
+assertEquals(undefined, ab[2 * pow31 - 1]);
var c = [];
c[pow30] = 30;
assertThrows("a.unshift(1);", RangeError);
assertEquals(0xffffffff, a.length);
assertEquals(10, a[0xffffffff]);
+assertEquals(0xffffffff, a.length);
assertEquals(undefined, a[0xfffffffe]);
a = [1,2,3];