| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index f852ca0de39dee015d82e03b5f7f326910688c56..9c531d43f6be9148bd88f31a5e51890316f66de9 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -6542,12 +6542,14 @@ Maybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate,
|
| return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object),
|
| key, desc, should_throw);
|
| }
|
| + if (object->IsJSTypedArray()) {
|
| + return JSTypedArray::DefineOwnProperty(
|
| + isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw);
|
| + }
|
| // TODO(neis): Special case for JSModuleNamespace?
|
|
|
| // OrdinaryDefineOwnProperty, by virtue of calling
|
| // DefineOwnPropertyIgnoreAttributes, can handle arguments (ES6 9.4.4.2)
|
| - // and IntegerIndexedExotics (ES6 9.4.5.3), with one exception:
|
| - // TODO(jkummerow): Setting an indexed accessor on a typed array should throw.
|
| return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
|
| desc, should_throw);
|
| }
|
| @@ -17435,6 +17437,100 @@ Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
|
| }
|
|
|
|
|
| +namespace {
|
| +
|
| +bool CanonicalNumericIndexString(Isolate* isolate,
|
| + Handle<Object> s,
|
| + Handle<Object>* index) {
|
| + DCHECK(s->IsString() || s->IsSmi());
|
| + if (s->IsSmi()) {
|
| + *index = s;
|
| + return true;
|
| + }
|
| + Handle<Object> value = String::ToNumber(Handle<String>::cast(s));
|
| + if (value->IsMinusZero() ||
|
| + // Avoid treating strings like "2E1" and "20" as the same key
|
| + Object::ToString(isolate, value).ToHandleChecked()->SameValue(*s)) {
|
| + *index = value;
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +} // anonymous namespace
|
| +
|
| +// ES#sec-integer-indexed-exotic-objects-defineownproperty-p-desc
|
| +// static
|
| +Maybe<bool> JSTypedArray::DefineOwnProperty(Isolate* isolate,
|
| + Handle<JSTypedArray> o,
|
| + Handle<Object> key,
|
| + PropertyDescriptor* desc,
|
| + ShouldThrow should_throw) {
|
| + // 1. Assert: IsPropertyKey(P) is true.
|
| + DCHECK(key->IsName() || key->IsNumber());
|
| + // 2. Assert: O is an Object that has a [[ViewedArrayBuffer]] internal slot.
|
| + // 3. If Type(P) is String, then
|
| + // ToPropertyKey returns Smi's too
|
| + if (key->IsString() || key->IsSmi()) {
|
| + // 3a. Let numericIndex be ! CanonicalNumericIndexString(P)
|
| + // 3b. If numericIndex is not undefined, then
|
| + Handle<Object> double_index;
|
| + if (CanonicalNumericIndexString(isolate, key, &double_index)) {
|
| + // 3b i. If IsInteger(numericIndex) is false, return false.
|
| + // 3b ii. If numericIndex = -0, return false.
|
| + // 3b iii. If numericIndex < 0, return false.
|
| + // FIXME: the standard allows up to 2^53 elements
|
| + uint32_t index;
|
| + if (double_index->IsMinusZero() || !double_index->ToUint32(&index)) {
|
| + RETURN_FAILURE(isolate, should_throw,
|
| + NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
|
| + }
|
| + // 3b iv. Let length be O.[[ArrayLength]].
|
| + uint32_t length = o->length()->Number();
|
| + // 3b v. If numericIndex ≥ length, return false.
|
| + if (index >= length) {
|
| + RETURN_FAILURE(isolate, should_throw,
|
| + NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
|
| + }
|
| + // 3b vi. If IsAccessorDescriptor(Desc) is true, return false.
|
| + if (PropertyDescriptor::IsAccessorDescriptor(desc)) {
|
| + RETURN_FAILURE(isolate, should_throw,
|
| + NewTypeError(MessageTemplate::kRedefineDisallowed, key));
|
| + }
|
| + // 3b vii. If Desc has a [[Configurable]] field and if
|
| + // Desc.[[Configurable]] is true, return false.
|
| + // 3b viii. If Desc has an [[Enumerable]] field and if Desc.[[Enumerable]]
|
| + // is false, return false.
|
| + // 3b ix. If Desc has a [[Writable]] field and if Desc.[[Writable]] is
|
| + // false, return false.
|
| + if ((desc->has_configurable() && desc->configurable()) ||
|
| + (desc->has_enumerable() && !desc->enumerable()) ||
|
| + (desc->has_writable() && !desc->writable())) {
|
| + RETURN_FAILURE(isolate, should_throw,
|
| + NewTypeError(MessageTemplate::kRedefineDisallowed, key));
|
| + }
|
| + // 3b x. If Desc has a [[Value]] field, then
|
| + // 3b x 1. Let value be Desc.[[Value]].
|
| + // 3b x 2. Return ? IntegerIndexedElementSet(O, numericIndex, value).
|
| + if (desc->has_value()) {
|
| + if (!desc->has_configurable()) desc->set_configurable(false);
|
| + if (!desc->has_enumerable()) desc->set_enumerable(true);
|
| + if (!desc->has_writable()) desc->set_writable(true);
|
| + Handle<Object> value = desc->value();
|
| + RETURN_ON_EXCEPTION_VALUE(isolate,
|
| + SetOwnElementIgnoreAttributes(
|
| + o, index, value, desc->ToAttributes()),
|
| + Nothing<bool>());
|
| + }
|
| + // 3b xi. Return true.
|
| + return Just(true);
|
| + }
|
| + }
|
| + // 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
|
| + return OrdinaryDefineOwnProperty(isolate, o, key, desc, should_throw);
|
| +}
|
| +
|
| +
|
| ExternalArrayType JSTypedArray::type() {
|
| switch (elements()->map()->instance_type()) {
|
| #define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \
|
|
|