Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Unified Diff: src/objects.cc

Issue 2431223005: Implement DefineOwnProperty for TypedArrays (Closed)
Patch Set: address comments and throw when needed Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/messages.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index f852ca0de39dee015d82e03b5f7f326910688c56..0fc49cdad47633b676b96f1904b5a6c86e395477 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6542,12 +6542,15 @@ 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);
}
@@ -17434,6 +17437,85 @@ Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
return isolate->factory()->NewNumberFromUint(result);
}
+static Handle<Object> CanonicalNumericIndexString(Isolate* isolate,
+ Handle<Object> s) {
+ DCHECK(s->IsString());
+ Handle<Object> index = String::ToNumber(Handle<String>::cast(s));
+ if (index->IsMinusZero()) return index;
+ // Avoid treating strings like "2E1" and "20" as the same key
+ if (!Object::ToString(isolate, index).ToHandleChecked()->SameValue(*s))
+ return isolate->factory()->undefined_value();
+ return index;
+}
+
+// ES6 9.4.5.3
+// 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)
+ Handle<Object> numeric_index =
+ key->IsSmi() ? key
+ : CanonicalNumericIndexString(isolate,
+ Handle<String>::cast(key));
+ // 3b. If numericIndex is not undefined, then
+ if (!numeric_index->IsUndefined(isolate)) {
+ // 3b i. If IsInteger(numericIndex) is false, return false.
+ // 3b ii. If numericIndex = -0, return false.
+ // 3b iii. If numericIndex < 0, return false.
+ int index = numeric_index->Number();
+ // FIXME: the standard allows up to 2^53 elements
+ if (!IsUint32Double(index))
+ RETURN_FAILURE(isolate, should_throw,
+ NewTypeError(MessageTemplate::kInvalidTypedArrayIndex));
+ // 3b iv. Let length be O.[[ArrayLength]].
+ int 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()) {
+ 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()) {
« src/messages.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698