Revision: 24705
Author:   [email protected]
Date:     Fri Oct 17 16:33:38 2014 UTC
Log:      Correct semantics for numerically indexed stores to typed arrays.

[email protected], [email protected]

Committed: https://code.google.com/p/v8/source/detail?r=24691

Review URL: https://codereview.chromium.org/652303002
https://code.google.com/p/v8/source/detail?r=24705

Modified:
 /branches/bleeding_edge/src/lookup.cc
 /branches/bleeding_edge/src/lookup.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js

=======================================
--- /branches/bleeding_edge/src/lookup.cc       Fri Oct 17 13:01:54 2014 UTC
+++ /branches/bleeding_edge/src/lookup.cc       Fri Oct 17 16:33:38 2014 UTC
@@ -307,6 +307,24 @@
     DCHECK_EQ(v8::internal::CONSTANT, property_details_.type());
   }
 }
+
+
+bool LookupIterator::IsSpecialNumericIndex() const {
+  if (GetStoreTarget()->IsJSTypedArray() && name()->IsString()) {
+    Handle<String> name_string = Handle<String>::cast(name());
+    if (name_string->length() > 0) {
+      double d =
+ StringToDouble(isolate()->unicode_cache(), *name_string, NO_FLAGS);
+      if (!std::isnan(d)) {
+        Factory* factory = isolate()->factory();
+        Handle<Object> num = factory->NewNumber(d);
+        Handle<String> roundtrip_string = factory->NumberToString(num);
+        if (String::Equals(name_string, roundtrip_string)) return true;
+      }
+    }
+  }
+  return false;
+}


 void LookupIterator::InternalizeName() {
=======================================
--- /branches/bleeding_edge/src/lookup.h        Fri Oct 17 13:01:54 2014 UTC
+++ /branches/bleeding_edge/src/lookup.h        Fri Oct 17 16:33:38 2014 UTC
@@ -138,6 +138,10 @@
   Handle<Object> GetDataValue() const;
   void WriteDataValue(Handle<Object> value);

+  // Checks whether the receiver is an indexed exotic object
+  // and name is a special numeric index.
+  bool IsSpecialNumericIndex() const;
+
   void InternalizeName();

  private:
=======================================
--- /branches/bleeding_edge/src/objects.cc      Fri Oct 17 13:19:45 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Fri Oct 17 16:33:38 2014 UTC
@@ -3077,6 +3077,10 @@
   // instead. If the prototype is Null, the proxy is detached.
   if (receiver->IsJSGlobalProxy()) return value;

+ // If the receiver is Indexed Exotic object (currently only typed arrays),
+  // disallow adding properties with numeric names.
+  if (it->IsSpecialNumericIndex()) return value;
+
   // Possibly migrate to the most up-to-date map that will be able to store
   // |value| under it->name() with |attributes|.
   it->PrepareTransitionToDataProperty(value, attributes, store_mode);
=======================================
--- /branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js Fri Oct 17 13:01:54 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/harmony/typedarrays.js Fri Oct 17 16:33:38 2014 UTC
@@ -481,6 +481,89 @@

 TestTypedArraySet();

+function TestTypedArraysWithIllegalIndices() {
+  var a = new Int32Array(100);
+
+  a[-10] = 10;
+  assertEquals(undefined, a[-10]);
+  a["-10"] = 10;
+  assertEquals(undefined, a["-10"]);
+
+  var s = "    -10";
+  a[s] = 10;
+  assertEquals(10, a[s]);
+  var s1 = "    -10   ";
+  a[s] = 10;
+  assertEquals(10, a[s]);
+
+  a["-1e2"] = 10;
+  assertEquals(10, a["-1e2"]);
+  assertEquals(undefined, a[-1e2]);
+
+  /* Chromium bug: 424619
+   * a[-Infinity] = 50;
+   * assertEquals(undefined, a[-Infinity]);
+   */
+  a[1.5] = 10;
+  assertEquals(undefined, a[1.5]);
+  var nan = Math.sqrt(-1);
+  a[nan] = 5;
+  assertEquals(5, a[nan]);
+
+  var x = 0;
+  var y = -0;
+  assertEquals(Infinity, 1/x);
+  assertEquals(-Infinity, 1/y);
+  a[x] = 5;
+  a[y] = 27;
+  assertEquals(27, a[x]);
+  assertEquals(27, a[y]);
+}
+
+TestTypedArraysWithIllegalIndices();
+
+function TestTypedArraysWithIllegalIndicesStrict() {
+  'use strict';
+  var a = new Int32Array(100);
+
+  a[-10] = 10;
+  assertEquals(undefined, a[-10]);
+  a["-10"] = 10;
+  assertEquals(undefined, a["-10"]);
+
+  var s = "    -10";
+  a[s] = 10;
+  assertEquals(10, a[s]);
+  var s1 = "    -10   ";
+  a[s] = 10;
+  assertEquals(10, a[s]);
+
+  a["-1e2"] = 10;
+  assertEquals(10, a["-1e2"]);
+  assertEquals(undefined, a[-1e2]);
+
+  /* Chromium bug: 424619
+   * a[-Infinity] = 50;
+   * assertEquals(undefined, a[-Infinity]);
+   */
+  a[1.5] = 10;
+  assertEquals(undefined, a[1.5]);
+  var nan = Math.sqrt(-1);
+  a[nan] = 5;
+  assertEquals(5, a[nan]);
+
+  var x = 0;
+  var y = -0;
+  assertEquals(Infinity, 1/x);
+  assertEquals(-Infinity, 1/y);
+  a[x] = 5;
+  a[y] = 27;
+  assertEquals(27, a[x]);
+  assertEquals(27, a[y]);
+}
+
+TestTypedArraysWithIllegalIndicesStrict();
+
 // DataView
 function TestDataViewConstructor() {
   var ab = new ArrayBuffer(256);

--
--
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