1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Flags: --allow-natives-syntax
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction test(mode) {
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var a = [];
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object.defineProperty(a, "length", { writable : false});
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function check(f) {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    try {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      f(a);
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } catch(e) { }
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertFalse(0 in a);
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(0, a.length);
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function push(a) {
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    a.push(3);
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == "fast properties") %ToFastProperties(a);
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(push);
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(push);
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(push);
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(push);
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(push);
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function unshift(a) {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    a.unshift(3);
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(unshift);
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(unshift);
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(unshift);
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  %OptimizeFunctionOnNextCall(unshift);
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  check(unshift);
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtest("fast properties");
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtest("normalized");
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar b = [];
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject.defineProperty(b.__proto__, "0", {
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set : function(v) {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    b.x = v;
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object.defineProperty(b, "length", { writable : false });
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  },
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  get: function() {
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return b.x;
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch});
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochb = [];
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtry {
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  b.push(3, 4, 5);
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} catch(e) { }
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertFalse(1 in b);
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertFalse(2 in b);
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals(0, b.length);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochb = [];
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtry {
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  b.unshift(3, 4, 5);
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} catch(e) { }
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertFalse(1 in b);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertFalse(2 in b);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals(0, b.length);
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochb = [1, 2];
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtry {
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  b.unshift(3, 4, 5);
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} catch(e) { }
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals(3, b[0]);
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals(4, b[1]);
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals(5, b[2]);
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals(1, b[3]);
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals(2, b[4]);
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals(5, b.length);
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochb = [1, 2];
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject.defineProperty(b.__proto__, "4", {
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set : function(v) {
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    b.z = v;
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object.defineProperty(b, "length", { writable : false });
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  },
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  get: function() {
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return b.z;
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch});
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtry {
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  b.unshift(3, 4, 5);
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} catch(e) { }
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(ulan): According to the ECMA-262 unshift should throw an exception
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// when moving b[0] to b[3] (see 15.4.4.13 step 6.d.ii). This is difficult
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to do with our current implementation of SmartMove() in src/array.js and
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// it will regress performance. Uncomment the following line once acceptable
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// solution is found:
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// assertFalse(2 in b);
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// assertFalse(3 in b);
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// assertEquals(2, b.length);
108