198 lines
4.0 KiB
JavaScript
198 lines
4.0 KiB
JavaScript
|
// Copyright 2018 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.
|
||
|
|
||
|
// Flags: --allow-natives-syntax
|
||
|
|
||
|
const MIN_DICTIONARY_INDEX = 8192;
|
||
|
|
||
|
(function ToStringThrows() {
|
||
|
function TestError() {}
|
||
|
|
||
|
let callCount = 0;
|
||
|
const a = [1, 2];
|
||
|
assertThrows(() => a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
throw new TestError;
|
||
|
}
|
||
|
}), TestError);
|
||
|
assertSame(1, callCount);
|
||
|
|
||
|
// Verifies cycle detection still works properly after thrown error.
|
||
|
assertSame('1,2', a.join());
|
||
|
})();
|
||
|
|
||
|
(function RecursiveJoinCall() {
|
||
|
const a = [1,2,3];
|
||
|
let callCount = 0;
|
||
|
const sep = {
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
return a.join('-');
|
||
|
}
|
||
|
};
|
||
|
assertSame('11-2-321-2-33', a.join(sep));
|
||
|
assertSame(1, callCount);
|
||
|
|
||
|
// Verify cycle detection works properly after nested call
|
||
|
assertSame('1,2,3', a.join());
|
||
|
})();
|
||
|
|
||
|
|
||
|
(function ArrayLengthIncreased() {
|
||
|
const a = [1,2,3];
|
||
|
let callCount = 0;
|
||
|
assertSame('1,2,3', a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a.push(4);
|
||
|
return ',';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
assertSame('1,2,3,4', a.join());
|
||
|
})();
|
||
|
|
||
|
(function ArrayLengthDecreased() {
|
||
|
const a = [1,2,3];
|
||
|
let callCount = 0;
|
||
|
assertSame('1,2,', a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a.pop();
|
||
|
return ',';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
assertSame('1,2', a.join());
|
||
|
})();
|
||
|
|
||
|
(function ArrayEmptied() {
|
||
|
const a = [1,2,3];
|
||
|
let callCount = 0;
|
||
|
assertSame(',,', a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a.length = 0;
|
||
|
return ',';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
})();
|
||
|
|
||
|
(function NumberDictionaryEmptied() {
|
||
|
const a = [];
|
||
|
a[0] = 1;
|
||
|
a[MIN_DICTIONARY_INDEX] = 2;
|
||
|
assertTrue(%HasDictionaryElements(a));
|
||
|
|
||
|
let callCount = 0;
|
||
|
assertSame('-'.repeat(MIN_DICTIONARY_INDEX), a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a.length = 0;
|
||
|
return '-';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
})();
|
||
|
|
||
|
(function NumberDictionaryEmptiedEmptySeparator() {
|
||
|
const a = [];
|
||
|
a[0] = 1;
|
||
|
a[MIN_DICTIONARY_INDEX] = 2;
|
||
|
assertTrue(%HasDictionaryElements(a));
|
||
|
|
||
|
let callCount = 0;
|
||
|
assertSame(''.repeat(MIN_DICTIONARY_INDEX), a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a.length = 0;
|
||
|
return '';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
})();
|
||
|
|
||
|
(function ElementsKindSmiToDoubles() {
|
||
|
const a = [1,2,3];
|
||
|
let callCount = 0;
|
||
|
assertTrue(%HasSmiElements(a));
|
||
|
assertSame('1.5,2,3', a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a[0] = 1.5;
|
||
|
assertTrue(%HasDoubleElements(a));
|
||
|
return ',';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
assertSame('1.5,2,3', a.join());
|
||
|
})();
|
||
|
|
||
|
(function ElementsKindDoublesToObjects() {
|
||
|
const a = [1.5, 2.5, 3.5];
|
||
|
let callCount = 0;
|
||
|
assertTrue(%HasDoubleElements(a));
|
||
|
assertSame('one,2.5,3.5', a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a[0] = 'one';
|
||
|
assertTrue(%HasObjectElements(a));
|
||
|
return ',';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
assertSame('one,2.5,3.5', a.join());
|
||
|
})();
|
||
|
|
||
|
(function ArrayIsNoLongerFast() {
|
||
|
const a = [1,2,3];
|
||
|
let callCount = 0;
|
||
|
assertSame('666,2,3', a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
Object.defineProperty(a, '0', {
|
||
|
get(){ return 666; }
|
||
|
});
|
||
|
return ',';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
assertSame('666,2,3', a.join());
|
||
|
})();
|
||
|
|
||
|
(function ArrayPrototypeUnset() {
|
||
|
const a = [1,2];
|
||
|
a.length = 3;
|
||
|
let callCount = 0;
|
||
|
assertSame('1,2,4', a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a.__proto__ = { '2': 4 };
|
||
|
return ',';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
a.__proto__ = Array.prototype;
|
||
|
assertSame('1,2,', a.join());
|
||
|
})();
|
||
|
|
||
|
(function ArrayPrototypeIsNoLongerFast() {
|
||
|
const a = [1,2,3];
|
||
|
let callCount = 0;
|
||
|
assertSame('1,2,777', a.join({
|
||
|
toString() {
|
||
|
callCount++;
|
||
|
a.pop();
|
||
|
Object.defineProperty(Array.prototype, '2', {
|
||
|
get(){ return 777; }
|
||
|
});
|
||
|
return ',';
|
||
|
}
|
||
|
}));
|
||
|
assertSame(1, callCount);
|
||
|
assertSame('1,2', a.join());
|
||
|
})();
|