[typedarray] ToNumber coercion is done only once for TA.p.fill

Update according to new spec change at
https://github.com/tc39/ecma262/pull/856

- Call ToNumber only once in BUILTIN
- Remove unused FillNumberSlowPath
- FillImpl assumes obj_value->IsNumber() is true
- Update test

Bug:v8:5929,chromium:702902

Change-Id: Ic83e6754d043582955b81c76e68f95e1c6b7e901
Reviewed-on: https://chromium-review.googlesource.com/465646
Reviewed-by: Daniel Ehrenberg <littledan@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44373}
This commit is contained in:
Loo Rong Jie 2017-04-03 17:34:29 +08:00 committed by Commit Bot
parent f9d2c5123e
commit 2b1b32253b
3 changed files with 13 additions and 46 deletions

View File

@ -195,6 +195,10 @@ BUILTIN(TypedArrayPrototypeFill) {
if (V8_UNLIKELY(array->WasNeutered())) return *array;
Handle<Object> obj_value = args.atOrUndefined(isolate, 1);
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, obj_value, Object::ToNumber(obj_value));
int64_t len = array->length_value();
int64_t start = 0;
int64_t end = len;
@ -227,8 +231,6 @@ BUILTIN(TypedArrayPrototypeFill) {
DCHECK_LE(end, len);
DCHECK_LE(count, len);
Handle<Object> obj_value = args.atOrUndefined(isolate, 1);
return array->GetElementsAccessor()->Fill(isolate, array, obj_value,
static_cast<uint32_t>(start),
static_cast<uint32_t>(end));

View File

@ -470,22 +470,6 @@ static void SortIndices(
}
}
static Object* FillNumberSlowPath(Isolate* isolate, Handle<JSTypedArray> array,
Handle<Object> obj_value,
uint32_t start, uint32_t end) {
Handle<Object> cast_value;
ElementsAccessor* elements = array->GetElementsAccessor();
for (uint32_t k = start; k < end; ++k) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, cast_value, Object::ToNumber(obj_value));
// TODO(caitp,cbruni): throw on neutered array
if (V8_UNLIKELY(array->WasNeutered())) return *array;
elements->Set(array, k, *cast_value);
}
return *array;
}
static Maybe<bool> IncludesValueSlowPath(Isolate* isolate,
Handle<JSObject> receiver,
Handle<Object> value,
@ -2878,24 +2862,14 @@ class TypedElementsAccessor
uint32_t end) {
Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
DCHECK(!array->WasNeutered());
DCHECK(obj_value->IsNumber());
ctype value;
if (obj_value->IsSmi()) {
value = BackingStore::from_int(Smi::cast(*obj_value)->value());
} else {
Handle<HeapObject> heap_obj_value = Handle<HeapObject>::cast(obj_value);
if (heap_obj_value->IsHeapNumber()) {
value = BackingStore::from_double(
HeapNumber::cast(*heap_obj_value)->value());
} else if (heap_obj_value->IsOddball()) {
value = BackingStore::from_double(
Oddball::ToNumber(Handle<Oddball>::cast(heap_obj_value))->Number());
} else if (heap_obj_value->IsString()) {
value = BackingStore::from_double(
String::ToNumber(Handle<String>::cast(heap_obj_value))->Number());
} else {
return FillNumberSlowPath(isolate, array, obj_value, start, end);
}
DCHECK(obj_value->IsHeapNumber());
value = BackingStore::from_double(HeapNumber::cast(*obj_value)->value());
}
// Ensure indexes are within array bounds

View File

@ -52,22 +52,13 @@ for (var constructor of typedArrayConstructors) {
assertArrayEquals([8, 8, 8, 8, 8], new constructor([0, 0, 0, 0, 0]).fill("8"));
// Test ToNumber
var s = "";
var p = new Proxy({}, {get(t,k) { s += k.toString() + '\n'; return Reflect.get(t, k)}})
var n = 1;
assertArrayEquals([1, 1], new constructor(2).fill({ valueOf() { return n++; } }));
assertEquals(2, n);
var s = [];
var p = new Proxy({}, { get(t,k) { s.push(k.toString()); return Reflect.get(t,k)} });
new constructor(3).fill(p);
assertEquals(s, `Symbol(Symbol.toPrimitive)
valueOf
toString
Symbol(Symbol.toStringTag)
Symbol(Symbol.toPrimitive)
valueOf
toString
Symbol(Symbol.toStringTag)
Symbol(Symbol.toPrimitive)
valueOf
toString
Symbol(Symbol.toStringTag)
`);
assertEquals(["Symbol(Symbol.toPrimitive)", "valueOf", "toString", "Symbol(Symbol.toStringTag)"], s);
// Shadowing length doesn't affect fill, unlike Array.prototype.fill
var a = new constructor([2, 2]);