Commit e3ad6930 authored by dslomov@chromium.org's avatar dslomov@chromium.org

Correct semantics for numerically indexed stores to typed arrays.

R=verwaest@chromium.org, ishell@chromium.org

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

Review URL: https://codereview.chromium.org/652303002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24705 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2dfefb42
......@@ -309,6 +309,24 @@ void LookupIterator::WriteDataValue(Handle<Object> value) {
}
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() {
if (name_->IsUniqueName()) return;
name_ = factory()->InternalizeString(Handle<String>::cast(name_));
......
......@@ -138,6 +138,10 @@ class LookupIterator FINAL BASE_EMBEDDED {
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:
......
......@@ -3077,6 +3077,10 @@ MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
// 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);
......
......@@ -481,6 +481,89 @@ function TestTypedArraySet() {
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);
......
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