Fix typed data views throwing.

Fixes #43204

BUG= http://dartbug.com/43204

Change-Id: I93ee6931900b79ac6755431c90d2b203ccf94ff1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181401
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Nate Bosch <nbosch@google.com>
This commit is contained in:
Lasse R.H. Nielsen 2021-01-29 09:24:45 +00:00 committed by commit-bot@chromium.org
parent 0c3696d76a
commit bb5b0ff0ce
4 changed files with 204 additions and 84 deletions

View file

@ -67,8 +67,8 @@ class NativeByteBuffer implements ByteBuffer {
}
Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) {
var storage =
this.asInt32List(offsetInBytes, length != null ? length * 4 : null);
length ??= (lengthInBytes - offsetInBytes) ~/ Int32x4List.bytesPerElement;
var storage = this.asInt32List(offsetInBytes, length * 4);
return NativeInt32x4List._externalStorage(storage);
}
@ -81,14 +81,14 @@ class NativeByteBuffer implements ByteBuffer {
}
Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) {
var storage =
this.asFloat32List(offsetInBytes, length != null ? length * 4 : null);
length ??= (lengthInBytes - offsetInBytes) ~/ Float32x4List.bytesPerElement;
var storage = this.asFloat32List(offsetInBytes, length * 4);
return NativeFloat32x4List._externalStorage(storage);
}
Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) {
var storage =
this.asFloat64List(offsetInBytes, length != null ? length * 2 : null);
length ??= (lengthInBytes - offsetInBytes) ~/ Float64x2List.bytesPerElement;
var storage = this.asFloat64List(offsetInBytes, length * 2);
return NativeFloat64x2List._externalStorage(storage);
}
@ -750,9 +750,9 @@ class NativeFloat32List extends NativeTypedArrayOfDouble
factory NativeFloat32List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Float32List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Float32List;
@ -767,9 +767,6 @@ class NativeFloat32List extends NativeTypedArrayOfDouble
static NativeFloat32List _create1(arg) =>
JS<NativeFloat32List>('!', 'new Float32Array(#)', arg);
static NativeFloat32List _create2(arg1, arg2) =>
JS<NativeFloat32List>('!', 'new Float32Array(#, #)', arg1, arg2);
static NativeFloat32List _create3(arg1, arg2, arg3) =>
JS<NativeFloat32List>('!', 'new Float32Array(#, #, #)', arg1, arg2, arg3);
}
@ -785,9 +782,9 @@ class NativeFloat64List extends NativeTypedArrayOfDouble
factory NativeFloat64List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Float64List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Float64List;
@ -801,9 +798,6 @@ class NativeFloat64List extends NativeTypedArrayOfDouble
static NativeFloat64List _create1(arg) =>
JS('NativeFloat64List', 'new Float64Array(#)', arg);
static NativeFloat64List _create2(arg1, arg2) =>
JS('NativeFloat64List', 'new Float64Array(#, #)', arg1, arg2);
static NativeFloat64List _create3(arg1, arg2, arg3) =>
JS('NativeFloat64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3);
}
@ -818,9 +812,9 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
factory NativeInt16List.view(
NativeByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Int16List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Int16List;
@ -839,9 +833,6 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
static NativeInt16List _create1(arg) =>
JS('NativeInt16List', 'new Int16Array(#)', arg);
static NativeInt16List _create2(arg1, arg2) =>
JS('NativeInt16List', 'new Int16Array(#, #)', arg1, arg2);
static NativeInt16List _create3(arg1, arg2, arg3) =>
JS('NativeInt16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3);
}
@ -856,9 +847,9 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
factory NativeInt32List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Int32List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Int32List;
@ -878,9 +869,6 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
static NativeInt32List _create1(arg) =>
JS<NativeInt32List>('!', 'new Int32Array(#)', arg);
static NativeInt32List _create2(arg1, arg2) =>
JS<NativeInt32List>('!', 'new Int32Array(#, #)', arg1, arg2);
static NativeInt32List _create3(arg1, arg2, arg3) =>
JS<NativeInt32List>('!', 'new Int32Array(#, #, #)', arg1, arg2, arg3);
}
@ -933,9 +921,9 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
factory NativeUint16List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Uint16List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Uint16List;
@ -955,9 +943,6 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
static NativeUint16List _create1(arg) =>
JS<NativeUint16List>('!', 'new Uint16Array(#)', arg);
static NativeUint16List _create2(arg1, arg2) =>
JS<NativeUint16List>('!', 'new Uint16Array(#, #)', arg1, arg2);
static NativeUint16List _create3(arg1, arg2, arg3) =>
JS<NativeUint16List>('!', 'new Uint16Array(#, #, #)', arg1, arg2, arg3);
}
@ -972,9 +957,9 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
factory NativeUint32List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Uint32List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Uint32List;
@ -994,9 +979,6 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
static NativeUint32List _create1(arg) =>
JS<NativeUint32List>('!', 'new Uint32Array(#)', arg);
static NativeUint32List _create2(arg1, arg2) =>
JS<NativeUint32List>('!', 'new Uint32Array(#, #)', arg1, arg2);
static NativeUint32List _create3(arg1, arg2, arg3) =>
JS<NativeUint32List>('!', 'new Uint32Array(#, #, #)', arg1, arg2, arg3);
}

View file

@ -68,8 +68,8 @@ class NativeByteBuffer implements ByteBuffer {
}
Int32x4List asInt32x4List([int offsetInBytes = 0, int? length]) {
var storage =
this.asInt32List(offsetInBytes, length != null ? length * 4 : null);
length ??= (lengthInBytes - offsetInBytes) ~/ Int32x4List.bytesPerElement;
var storage = this.asInt32List(offsetInBytes, length * 4);
return NativeInt32x4List._externalStorage(storage);
}
@ -82,14 +82,14 @@ class NativeByteBuffer implements ByteBuffer {
}
Float32x4List asFloat32x4List([int offsetInBytes = 0, int? length]) {
var storage =
this.asFloat32List(offsetInBytes, length != null ? length * 4 : null);
length ??= (lengthInBytes - offsetInBytes) ~/ Float32x4List.bytesPerElement;
var storage = this.asFloat32List(offsetInBytes, length * 4);
return NativeFloat32x4List._externalStorage(storage);
}
Float64x2List asFloat64x2List([int offsetInBytes = 0, int? length]) {
var storage =
this.asFloat64List(offsetInBytes, length != null ? length * 2 : null);
length ??= (lengthInBytes - offsetInBytes) ~/ Float64x2List.bytesPerElement;
var storage = this.asFloat64List(offsetInBytes, length * 2);
return NativeFloat64x2List._externalStorage(storage);
}
@ -747,9 +747,9 @@ class NativeFloat32List extends NativeTypedArrayOfDouble
factory NativeFloat32List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Float32List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Float32List;
@ -768,9 +768,6 @@ class NativeFloat32List extends NativeTypedArrayOfDouble
static NativeFloat32List _create1(arg) =>
JS('NativeFloat32List', 'new Float32Array(#)', arg);
static NativeFloat32List _create2(arg1, arg2) =>
JS('NativeFloat32List', 'new Float32Array(#, #)', arg1, arg2);
static NativeFloat32List _create3(arg1, arg2, arg3) =>
JS('NativeFloat32List', 'new Float32Array(#, #, #)', arg1, arg2, arg3);
}
@ -786,9 +783,9 @@ class NativeFloat64List extends NativeTypedArrayOfDouble
factory NativeFloat64List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Float64List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Float64List;
@ -807,9 +804,6 @@ class NativeFloat64List extends NativeTypedArrayOfDouble
static NativeFloat64List _create1(arg) =>
JS('NativeFloat64List', 'new Float64Array(#)', arg);
static NativeFloat64List _create2(arg1, arg2) =>
JS('NativeFloat64List', 'new Float64Array(#, #)', arg1, arg2);
static NativeFloat64List _create3(arg1, arg2, arg3) =>
JS('NativeFloat64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3);
}
@ -824,9 +818,9 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
factory NativeInt16List.view(
NativeByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Int16List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Int16List;
@ -850,9 +844,6 @@ class NativeInt16List extends NativeTypedArrayOfInt implements Int16List {
static NativeInt16List _create1(arg) =>
JS('NativeInt16List', 'new Int16Array(#)', arg);
static NativeInt16List _create2(arg1, arg2) =>
JS('NativeInt16List', 'new Int16Array(#, #)', arg1, arg2);
static NativeInt16List _create3(arg1, arg2, arg3) =>
JS('NativeInt16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3);
}
@ -867,9 +858,9 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
factory NativeInt32List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Int32List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Int32List;
@ -893,9 +884,6 @@ class NativeInt32List extends NativeTypedArrayOfInt implements Int32List {
static NativeInt32List _create1(arg) =>
JS('NativeInt32List', 'new Int32Array(#)', arg);
static NativeInt32List _create2(arg1, arg2) =>
JS('NativeInt32List', 'new Int32Array(#, #)', arg1, arg2);
static NativeInt32List _create3(arg1, arg2, arg3) =>
JS('NativeInt32List', 'new Int32Array(#, #, #)', arg1, arg2, arg3);
}
@ -953,9 +941,9 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
factory NativeUint16List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Uint16List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Uint16List;
@ -979,9 +967,6 @@ class NativeUint16List extends NativeTypedArrayOfInt implements Uint16List {
static NativeUint16List _create1(arg) =>
JS('NativeUint16List', 'new Uint16Array(#)', arg);
static NativeUint16List _create2(arg1, arg2) =>
JS('NativeUint16List', 'new Uint16Array(#, #)', arg1, arg2);
static NativeUint16List _create3(arg1, arg2, arg3) =>
JS('NativeUint16List', 'new Uint16Array(#, #, #)', arg1, arg2, arg3);
}
@ -996,9 +981,9 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
factory NativeUint32List.view(
ByteBuffer buffer, int offsetInBytes, int? length) {
_checkViewArguments(buffer, offsetInBytes, length);
return length == null
? _create2(buffer, offsetInBytes)
: _create3(buffer, offsetInBytes, length);
length ??=
(buffer.lengthInBytes - offsetInBytes) ~/ Uint32List.bytesPerElement;
return _create3(buffer, offsetInBytes, length);
}
Type get runtimeType => Uint32List;
@ -1022,9 +1007,6 @@ class NativeUint32List extends NativeTypedArrayOfInt implements Uint32List {
static NativeUint32List _create1(arg) =>
JS('NativeUint32List', 'new Uint32Array(#)', arg);
static NativeUint32List _create2(arg1, arg2) =>
JS('NativeUint32List', 'new Uint32Array(#, #)', arg1, arg2);
static NativeUint32List _create3(arg1, arg2, arg3) =>
JS('NativeUint32List', 'new Uint32Array(#, #, #)', arg1, arg2, arg3);
}

View file

@ -0,0 +1,78 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Regression test for https://github.com/dart-lang/sdk/issues/43204
import 'dart:typed_data';
import "package:expect/expect.dart";
void main() {
// This test should not throw.
// The created views should extend as far as possible in each case.
var buffer = Uint8List(127).buffer;
var f32l = buffer.asFloat32List();
Expect.equals(31, f32l.length);
Expect.equals(31 * Float32List.bytesPerElement, f32l.lengthInBytes);
f32l = buffer.asFloat32List(8);
Expect.equals(29, f32l.length);
Expect.equals(29 * Float32List.bytesPerElement, f32l.lengthInBytes);
var f64l = buffer.asFloat64List();
Expect.equals(15, f64l.length);
Expect.equals(15 * Float64List.bytesPerElement, f64l.lengthInBytes);
f64l = buffer.asFloat64List(8);
Expect.equals(14, f64l.length);
Expect.equals(14 * Float64List.bytesPerElement, f64l.lengthInBytes);
var i16l = buffer.asInt16List();
Expect.equals(63, i16l.length);
Expect.equals(63 * Int16List.bytesPerElement, i16l.lengthInBytes);
i16l = buffer.asInt16List(8);
Expect.equals(59, i16l.length);
Expect.equals(59 * Int16List.bytesPerElement, i16l.lengthInBytes);
var i32l = buffer.asInt32List();
Expect.equals(31, i32l.length);
Expect.equals(31 * Int32List.bytesPerElement, i32l.lengthInBytes);
i32l = buffer.asInt32List(8);
Expect.equals(29, i32l.length);
Expect.equals(29 * Int32List.bytesPerElement, i32l.lengthInBytes);
var u16l = buffer.asUint16List();
Expect.equals(63, u16l.length);
Expect.equals(63 * Uint16List.bytesPerElement, u16l.lengthInBytes);
u16l = buffer.asUint16List(8);
Expect.equals(59, u16l.length);
Expect.equals(59 * Uint16List.bytesPerElement, u16l.lengthInBytes);
var u32l = buffer.asUint32List();
Expect.equals(31, u32l.length);
Expect.equals(31 * Uint32List.bytesPerElement, u32l.lengthInBytes);
u32l = buffer.asUint32List(8);
Expect.equals(29, u32l.length);
Expect.equals(29 * Uint32List.bytesPerElement, u32l.lengthInBytes);
var f32x4l = buffer.asFloat32x4List();
Expect.equals(7, f32x4l.length);
Expect.equals(7 * Float32x4List.bytesPerElement, f32x4l.lengthInBytes);
f32x4l = buffer.asFloat32x4List(16);
Expect.equals(6, f32x4l.length);
Expect.equals(6 * Float32x4List.bytesPerElement, f32x4l.lengthInBytes);
var f64x2l = buffer.asFloat64x2List();
Expect.equals(7, f64x2l.length);
Expect.equals(7 * Float64x2List.bytesPerElement, f64x2l.lengthInBytes);
f64x2l = buffer.asFloat64x2List(16);
Expect.equals(6, f64x2l.length);
Expect.equals(6 * Float64x2List.bytesPerElement, f64x2l.lengthInBytes);
var i32x4l = buffer.asInt32x4List();
Expect.equals(7, i32x4l.length);
Expect.equals(7 * Int32x4List.bytesPerElement, i32x4l.lengthInBytes);
i32x4l = buffer.asInt32x4List(16);
Expect.equals(6, i32x4l.length);
Expect.equals(6 * Int32x4List.bytesPerElement, i32x4l.lengthInBytes);
}

View file

@ -0,0 +1,78 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Regression test for https://github.com/dart-lang/sdk/issues/43204
import 'dart:typed_data';
import "package:expect/expect.dart";
void main() {
// This test should not throw.
// The created views should extend as far as possible in each case.
var buffer = Uint8List(127).buffer;
var f32l = buffer.asFloat32List();
Expect.equals(31, f32l.length);
Expect.equals(31 * Float32List.bytesPerElement, f32l.lengthInBytes);
f32l = buffer.asFloat32List(8);
Expect.equals(29, f32l.length);
Expect.equals(29 * Float32List.bytesPerElement, f32l.lengthInBytes);
var f64l = buffer.asFloat64List();
Expect.equals(15, f64l.length);
Expect.equals(15 * Float64List.bytesPerElement, f64l.lengthInBytes);
f64l = buffer.asFloat64List(8);
Expect.equals(14, f64l.length);
Expect.equals(14 * Float64List.bytesPerElement, f64l.lengthInBytes);
var i16l = buffer.asInt16List();
Expect.equals(63, i16l.length);
Expect.equals(63 * Int16List.bytesPerElement, i16l.lengthInBytes);
i16l = buffer.asInt16List(8);
Expect.equals(59, i16l.length);
Expect.equals(59 * Int16List.bytesPerElement, i16l.lengthInBytes);
var i32l = buffer.asInt32List();
Expect.equals(31, i32l.length);
Expect.equals(31 * Int32List.bytesPerElement, i32l.lengthInBytes);
i32l = buffer.asInt32List(8);
Expect.equals(29, i32l.length);
Expect.equals(29 * Int32List.bytesPerElement, i32l.lengthInBytes);
var u16l = buffer.asUint16List();
Expect.equals(63, u16l.length);
Expect.equals(63 * Uint16List.bytesPerElement, u16l.lengthInBytes);
u16l = buffer.asUint16List(8);
Expect.equals(59, u16l.length);
Expect.equals(59 * Uint16List.bytesPerElement, u16l.lengthInBytes);
var u32l = buffer.asUint32List();
Expect.equals(31, u32l.length);
Expect.equals(31 * Uint32List.bytesPerElement, u32l.lengthInBytes);
u32l = buffer.asUint32List(8);
Expect.equals(29, u32l.length);
Expect.equals(29 * Uint32List.bytesPerElement, u32l.lengthInBytes);
var f32x4l = buffer.asFloat32x4List();
Expect.equals(7, f32x4l.length);
Expect.equals(7 * Float32x4List.bytesPerElement, f32x4l.lengthInBytes);
f32x4l = buffer.asFloat32x4List(16);
Expect.equals(6, f32x4l.length);
Expect.equals(6 * Float32x4List.bytesPerElement, f32x4l.lengthInBytes);
var f64x2l = buffer.asFloat64x2List();
Expect.equals(7, f64x2l.length);
Expect.equals(7 * Float64x2List.bytesPerElement, f64x2l.lengthInBytes);
f64x2l = buffer.asFloat64x2List(16);
Expect.equals(6, f64x2l.length);
Expect.equals(6 * Float64x2List.bytesPerElement, f64x2l.lengthInBytes);
var i32x4l = buffer.asInt32x4List();
Expect.equals(7, i32x4l.length);
Expect.equals(7 * Int32x4List.bytesPerElement, i32x4l.lengthInBytes);
i32x4l = buffer.asInt32x4List(16);
Expect.equals(6, i32x4l.length);
Expect.equals(6 * Int32x4List.bytesPerElement, i32x4l.lengthInBytes);
}