[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:
parent
f9d2c5123e
commit
2b1b32253b
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user