blob: 029983b097e0ce957048563f5d98296c9edbad34 [file] [log] [blame]
// 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.
// Flags: --allow-natives-syntax
// NOTE:
// Tests in this file are meant to run in the presence of an invalidated
// NoElementsProtector, as effected by the following line.
Array.prototype[0] = 42;
delete Array.prototype[0];
(function TestBasics() {
var a = [1, 2];
var b = [...a];
assertArrayEquals([1, 2], b)
assertArrayEquals(['a', 'b', 'c', 'd', 'e', 'f'],
['a', ...'bc', 'd', ...'ef'])
})();
var log = [];
function* gen(n) {
log.push(n, 1);
yield 1;
log.push(n, 2);
yield 2;
log.push(n, 3);
yield 3;
log.push(n, 'done');
}
function id(v) {
log.push(v);
return v;
}
(function TestGenerator() {
assertArrayEquals([1, 2, 3], [...gen('a')]);
assertArrayEquals(['x', 1, 2, 3, 'y', 1, 2, 3, 'z'],
['x', ...gen('a'), 'y', ...gen('b'), 'z']);
})();
(function TestOrderOfExecution() {
log = [];
assertArrayEquals(['x', 1, 2, 3, 'y', 1, 2, 3, 'z'],
[id('x'), ...gen('a'), id('y'), ...gen('b'), id('z')]);
assertArrayEquals([
'x', 'a', 1, 'a', 2, 'a', 3, 'a', 'done',
'y', 'b', 1, 'b', 2, 'b', 3, 'b', 'done',
'z'
], log);
})();
(function TestNotIterable() {
var a;
assertThrows(function() {
a = [...42];
}, TypeError);
assertSame(undefined, a);
})();
(function TestInvalidIterator() {
var iter = {
[Symbol.iterator]: 42
};
var a;
assertThrows(function() {
a = [...iter];
}, TypeError);
assertSame(undefined, a);
})();
(function TestIteratorNotAnObject() {
var iter = {
[Symbol.iterator]() {
return 42;
}
};
var a;
assertThrows(function() {
a = [...iter];
}, TypeError);
assertSame(undefined, a);
})();
(function TestIteratorNoNext() {
var iter = {
[Symbol.iterator]() {
return {};
}
};
var a;
assertThrows(function() {
a = [...iter];
}, TypeError);
assertSame(undefined, a);
})();
(function TestIteratorResultDoneThrows() {
function MyError() {}
var iter = {
[Symbol.iterator]() {
return {
next() {
return {
get done() {
throw new MyError();
}
}
}
};
}
};
var a;
assertThrows(function() {
a = [...iter];
}, MyError);
assertSame(undefined, a);
})();
(function TestIteratorResultValueThrows() {
function MyError() {}
var iter = {
[Symbol.iterator]() {
return {
next() {
return {
done: false,
get value() {
throw new MyError();
}
}
}
};
}
};
var a;
assertThrows(function() {
a = [...iter];
}, MyError);
assertSame(undefined, a);
})();
(function TestOptimize() {
function f() {
return [...'abc'];
}
%PrepareFunctionForOptimization(f);
assertArrayEquals(['a', 'b', 'c'], f());
%OptimizeFunctionOnNextCall(f);
assertArrayEquals(['a', 'b', 'c'], f());
})();
(function TestDeoptimize() {
var iter = {
[Symbol.iterator]() {
var i = 0;
return {
next() {
%DeoptimizeFunction(f);
return {value: ++i, done: i === 3};
}
};
}
};
function f() {
return [0, ...iter];
}
assertArrayEquals([0, 1, 2], f());
})();
(function TestPrototypeSetter1() {
Object.defineProperty(Array.prototype, 3, {set() {throw 666}})
Object.defineProperty(Array.prototype, 4, {set() {throw 666}})
function f() {
return ['a', ...['b', 'c', 'd'], 'e']
}
%PrepareFunctionForOptimization(f);
assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
%OptimizeFunctionOnNextCall(f);
assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
delete Array.prototype[3];
delete Array.prototype[4];
})();
(function TestPrototypeSetter2() {
Object.defineProperty(Array.prototype.__proto__, 3, {set() {throw 666}})
Object.defineProperty(Array.prototype.__proto__, 4, {set() {throw 666}})
function f() {
return ['a', ...['b', 'c', 'd'], 'e']
}
%PrepareFunctionForOptimization(f);
assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
%OptimizeFunctionOnNextCall(f);
assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
delete Array.prototype.__proto__[3];
delete Array.prototype.__proto__[4];
})();
(function TestPrototypeProxy() {
const backup = Array.prototype.__proto__;
Array.prototype.__proto__ = new Proxy({}, {set() {throw 666}});
function f() {
return ['a', ...['b', 'c', 'd'], 'e']
}
%PrepareFunctionForOptimization(f);
assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
%OptimizeFunctionOnNextCall(f);
assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
Object.setPrototypeOf(Array.prototype, backup);
})();