Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge r244950 - TypedArrays should not store properties that are cano…
…nical numeric indices https://bugs.webkit.org/show_bug.cgi?id=197228 <rdar://problem/49557381> Reviewed by Saam Barati. JSTests: * stress/array-species-config-array-constructor.js: (test): * stress/put-direct-index-broken-2.js: * stress/typed-array-canonical-numeric-index-string.js: Added. (makeTest.assert): (makeTest): (const.testInvalidIndices.makeTest.set assert): (const.testInvalidIndices.makeTest): (const.makeTestValidIndex.configurable.set assert): (const.makeTestValidIndex.configurable): * stress/typedarray-access-monomorphic-neutered.js: (checkNoException): (testNoException): (testFTLNoException): * stress/typedarray-access-neutered.js: (testNoException): * stress/typedarray-getownproperty-not-configurable.js: (foo): * test262/expectations.yaml: Source/JavaScriptCore: According to the spec[1]: - TypedArrays should not perform an ordinary GetOwnProperty/SetOwnProperty if the index is a CanonicalNumericIndexString, but invalid according to IntegerIndexedElementGet and similar functions. I.e., there are a few properties that should not be set in a TypedArray, like NaN, Infinity and -0. - On DefineOwnProperty, the out-of-bounds check should be performed before validating the property descriptor. - On GetOwnProperty, the returned descriptor for numeric properties should have writable set to true. [1]: https://www.ecma-international.org/ecma-262/9.0/index.html#sec-integer-indexed-exotic-objects-defineownproperty-p-desc * CMakeLists.txt: * JavaScriptCore.xcodeproj/project.pbxproj: * runtime/JSGenericTypedArrayViewInlines.h: (JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlot): (JSC::JSGenericTypedArrayView<Adaptor>::put): (JSC::JSGenericTypedArrayView<Adaptor>::defineOwnProperty): (JSC::JSGenericTypedArrayView<Adaptor>::getOwnPropertySlotByIndex): (JSC::JSGenericTypedArrayView<Adaptor>::putByIndex): * runtime/PropertyName.h: (JSC::isCanonicalNumericIndexString): LayoutTests: * fast/canvas/canvas-ImageData-behaviour-expected.txt: * fast/canvas/canvas-ImageData-behaviour.js:
- Loading branch information
1 parent
9b9dc27
commit 4f458ee
Showing
16 changed files
with
292 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
JSTests/stress/typed-array-canonical-numeric-index-string.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//@ requireOptions("--forceEagerCompilation=true", "--osrExitCountForReoptimization=10", "--useConcurrentJIT=0") | ||
|
||
const typedArrays = [ | ||
Uint8ClampedArray, | ||
Uint8Array, | ||
Uint16Array, | ||
Uint32Array, | ||
Int8Array, | ||
Int16Array, | ||
Int32Array, | ||
Float32Array, | ||
Float64Array, | ||
]; | ||
|
||
const failures = new Set(); | ||
|
||
let value = 0; | ||
function makeTest(test) { | ||
noInline(test); | ||
|
||
function assert(typedArray, condition, message) { | ||
if (!condition) | ||
failures.add(`${typedArray.name}: ${message}`); | ||
} | ||
|
||
function testFor(typedArray, key) { | ||
return new Function('key', 'typedArray', 'test', 'assert', ` | ||
const value = ${value++} % 128; | ||
const u8 = new typedArray(1); | ||
u8[key] = value; | ||
test(u8, key, value, assert); | ||
`).bind(undefined, key, typedArray, test, assert.bind(undefined, typedArray)); | ||
}; | ||
|
||
return function(keys) { | ||
for (let typedArray of typedArrays) { | ||
for (let key of keys) { | ||
const runTest = testFor(typedArray, key); | ||
noInline(runTest); | ||
for (let i = 0; i < 10; i++) { | ||
runTest(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
const testInvalidIndices = makeTest((array, key, value, assert) => { | ||
assert(array[key] === undefined, `${key.toString()} should not be set`); | ||
assert(!(key in array), `${key.toString()} should not be in array`); | ||
|
||
const keys = Object.keys(array); | ||
assert(keys.length === 1, `no new keys should be added`); | ||
assert(keys[0] === '0', `'0' should be the only key`); | ||
assert(array[0] === 0, `offset 0 should not have been modified`); | ||
|
||
assert(array.hasOwnProperty(key) === false, `hasOwnProperty(${key.toString()}) should be false`); | ||
assert(Object.getOwnPropertyDescriptor(array, key) === undefined, `Object.getOwnPropertyDescriptor(${key.toString()}) should be undefined`); | ||
}); | ||
|
||
testInvalidIndices([ | ||
'-0', | ||
'-1', | ||
-1, | ||
1, | ||
'Infinity', | ||
'-Infinity', | ||
'NaN', | ||
'0.1', | ||
'4294967294', | ||
'4294967295', | ||
'4294967296', | ||
]); | ||
|
||
const makeTestValidIndex = (configurable) => | ||
(array, key, value, assert) => { | ||
assert(array[key] === value, `${key.toString()} should be set to ${value}`); | ||
assert(key in array, `should contain key ${key.toString()}`); | ||
|
||
assert(array.hasOwnProperty(key) === true, `hasOwnProperty(${key.toString()}) should be true`); | ||
const descriptor = Object.getOwnPropertyDescriptor(array, key); | ||
assert(typeof descriptor === 'object', `Object.getOwnPropertyDescriptor(${key.toString()}) return an object`); | ||
assert(descriptor.value === value, `descriptor.value should be ${value}`); | ||
assert(descriptor.writable === true, `descriptor.writable should be true`); | ||
assert(descriptor.enumerable === true, `descriptor.enumerable should be true`); | ||
assert(descriptor.configurable === configurable, `descriptor.configurable should be ${configurable}`); | ||
}; | ||
|
||
const testValidConfigurableIndices = makeTest(makeTestValidIndex(true)); | ||
|
||
testValidConfigurableIndices([ | ||
'01', | ||
'0.10', | ||
'+Infinity', | ||
'-NaN', | ||
'-0.0', | ||
Symbol('1'), | ||
]); | ||
|
||
testValidNonConfigurableIndices = makeTest(makeTestValidIndex(false)) | ||
testValidNonConfigurableIndices([ | ||
'0', | ||
0, | ||
]); | ||
|
||
if (failures.size) | ||
throw new Error(`Subtests failed:\n${Array.from(failures).join('\n')}`); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.