Reviewers: Dan Ehrenberg, adamk,

Message:
PTAL, thanks.

Description:
Only evaluate length once in %TypedArray%.prototype.set

The ES6 spec for this function declares that ToLength
should only be called once. We were evaluating it multiple
times, so if length was an object with a valueOf method,
we could see effects take place multiple times.

[email protected]
LOG=N
BUG=v8:4218

Please review this at https://codereview.chromium.org/1237583005/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+55, -0 lines):
  M src/typedarray.js
  A test/mjsunit/es6/typedarray-set-length.js


Index: src/typedarray.js
diff --git a/src/typedarray.js b/src/typedarray.js
index ce52cdf15c0b50db12eb9c904fd1781ce30acf26..8e18b5e66e08755ec7f9389530eef640100b4119 100644
--- a/src/typedarray.js
+++ b/src/typedarray.js
@@ -330,6 +330,7 @@ function TypedArraySet(obj, offset) {
         }
         return;
       }
+      l = $toLength(l);
       if (intOffset + l > this.length) {
         throw MakeRangeError(kTypedArraySetSourceTooLarge);
       }
Index: test/mjsunit/es6/typedarray-set-length.js
diff --git a/test/mjsunit/es6/typedarray-set-length.js b/test/mjsunit/es6/typedarray-set-length.js
new file mode 100644
index 0000000000000000000000000000000000000000..6dd5bf76e0a91397bd2f1c0e7b5e5cf49e16cbdc
--- /dev/null
+++ b/test/mjsunit/es6/typedarray-set-length.js
@@ -0,0 +1,54 @@
+// Copyright 2015 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.
+
+var typedArrayConstructors = [
+  Uint8Array,
+  Int8Array,
+  Uint16Array,
+  Int16Array,
+  Uint32Array,
+  Int32Array,
+  Uint8ClampedArray,
+  Float32Array,
+  Float64Array
+];
+
+var lengthCalled = false;
+function lengthValue() {
+  assertFalse(lengthCalled);
+  lengthCalled = true;
+  return 5;
+}
+
+// ToLength should convert these to usable lengths.
+var goodNonIntegerLengths = [
+  function() { return 4.6; },
+  function() { return -5; },
+  function() { return NaN; },
+  function() { return "5"; },
+  function() { return "abc"; },
+  function() { return true; },
+  function() { return null; },
+  function() { return undefined; }
+];
+
+// This will fail if you use ToLength on it.
+function badNonIntegerLength() {
+  return Symbol("5");
+}
+
+for (var constructor of typedArrayConstructors) {
+  lengthCalled = false;
+  var a = new constructor(10);
+  a.set({length: {valueOf: lengthValue}});
+  assertTrue(lengthCalled);
+
+  for (var lengthFun of goodNonIntegerLengths) {
+    a.set({length: {valueOf: lengthFun}});
+  }
+
+  assertThrows(function() {
+    a.set({length: {valueOf: badNonIntegerLength}});
+  }, TypeError);
+}


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to