Commit c5ad59f4 authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[builtins] Use length field in TypedArrayConstructByArrayLike.

The byte_length field of the TypedArray is not set to 0 on neutering,
but JSArrayBufferView::byte_length() returns 0 if WasNeutered() is
true. We should use the length property here instead.

We can just short-circuit if the length is 0. Added checks to the
memcpy path that assert length and neutered status are sane.

Bug:chromium:707472,chromium:707595,chromium:707364,chromium:707410

Change-Id: Ia1dec53f175357673012cbbc5e2fc40207e03623
Reviewed-on: https://chromium-review.googlesource.com/465987Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44336}
parent 953bdee0
...@@ -533,14 +533,17 @@ TF_BUILTIN(TypedArrayConstructByArrayLike, TypedArrayBuiltinsAssembler) { ...@@ -533,14 +533,17 @@ TF_BUILTIN(TypedArrayConstructByArrayLike, TypedArrayBuiltinsAssembler) {
Node* byte_offset = SmiConstant(0); Node* byte_offset = SmiConstant(0);
Node* initialize = BooleanConstant(false); Node* initialize = BooleanConstant(false);
Label invalid_length(this), fast_copy(this); Label invalid_length(this), fill(this), fast_copy(this);
// The caller has looked up length on array_like, which is observable. // The caller has looked up length on array_like, which is observable.
length = ToSmiLength(length, context, &invalid_length); length = ToSmiLength(length, context, &invalid_length);
InitializeBasedOnLength(holder, length, element_size, byte_offset, initialize, InitializeBasedOnLength(holder, length, element_size, byte_offset, initialize,
context); context);
GotoIf(SmiNotEqual(length, SmiConstant(0)), &fill);
Return(UndefinedConstant());
Bind(&fill);
Node* holder_kind = LoadMapElementsKind(LoadMap(holder)); Node* holder_kind = LoadMapElementsKind(LoadMap(holder));
Node* source_kind = LoadMapElementsKind(LoadMap(array_like)); Node* source_kind = LoadMapElementsKind(LoadMap(array_like));
GotoIf(Word32Equal(holder_kind, source_kind), &fast_copy); GotoIf(Word32Equal(holder_kind, source_kind), &fast_copy);
...@@ -558,12 +561,14 @@ TF_BUILTIN(TypedArrayConstructByArrayLike, TypedArrayBuiltinsAssembler) { ...@@ -558,12 +561,14 @@ TF_BUILTIN(TypedArrayConstructByArrayLike, TypedArrayBuiltinsAssembler) {
Node* holder_data_ptr = LoadDataPtr(holder); Node* holder_data_ptr = LoadDataPtr(holder);
Node* source_data_ptr = LoadDataPtr(array_like); Node* source_data_ptr = LoadDataPtr(array_like);
// When the typed arrays have the same elements kind, their byte_length will // Calculate the byte length. We shouldn't be trying to copy if the typed
// be exactly the same, so we don't need to calculate it. The byte_length // array was neutered.
// already takes into account the byte_offset, so we don't need to use that CSA_ASSERT(this, SmiNotEqual(length, SmiConstant(0)));
// here. CSA_ASSERT(this, Word32Equal(IsDetachedBuffer(LoadObjectField(
Node* byte_length = array_like, JSTypedArray::kBufferOffset)),
LoadObjectField(array_like, JSArrayBufferView::kByteLengthOffset); Int32Constant(0)));
Node* byte_length = SmiMul(length, element_size);
CSA_ASSERT(this, ByteLengthIsValid(byte_length)); CSA_ASSERT(this, ByteLengthIsValid(byte_length));
Node* byte_length_intptr = ChangeNumberToIntPtr(byte_length); Node* byte_length_intptr = ChangeNumberToIntPtr(byte_length);
CSA_ASSERT(this, UintPtrLessThanOrEqual( CSA_ASSERT(this, UintPtrLessThanOrEqual(
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var a = new Uint8Array(1024*1024);
%ArrayBufferNeuter(a.buffer);
var b = new Uint8Array(a);
assertEquals(0, b.length);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment