1// Copyright 2012 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Flags: --allow-natives-syntax
29
30// IC and Crankshaft support for smi-only elements in dynamic array literals.
31function get(foo) { return foo; }  // Used to generate dynamic values.
32
33function array_natives_test() {
34
35  // Ensure small array literals start in specific element kind mode.
36  assertTrue(%HasFastSmiElements([]));
37  assertTrue(%HasFastSmiElements([1]));
38  assertTrue(%HasFastSmiElements([1,2]));
39  assertTrue(%HasFastDoubleElements([1.1]));
40  assertTrue(%HasFastDoubleElements([1.1,2]));
41
42  // This code exists to eliminate the learning influence of AllocationSites
43  // on the following tests.
44  var __sequence = 0;
45  function make_array_string(literal) {
46    this.__sequence = this.__sequence + 1;
47    return "/* " + this.__sequence + " */  " + literal;
48  }
49  function make_array(literal) {
50    return eval(make_array_string(literal));
51  }
52
53  // Push
54  var a0 = make_array("[1, 2, 3]");
55  assertTrue(%HasFastSmiElements(a0));
56  a0.push(4);
57  assertTrue(%HasFastSmiElements(a0));
58  a0.push(1.3);
59  assertTrue(%HasFastDoubleElements(a0));
60  a0.push(1.5);
61  assertTrue(%HasFastDoubleElements(a0));
62  a0.push({});
63  assertTrue(%HasFastObjectElements(a0));
64  a0.push({});
65  assertTrue(%HasFastObjectElements(a0));
66  assertEquals([1,2,3,4,1.3,1.5,{},{}], a0);
67
68  // Concat
69  var a1;
70  a1 = [1,2,3].concat([]);
71  assertTrue(%HasFastSmiElements(a1));
72  assertEquals([1,2,3], a1);
73  a1 = [1,2,3].concat([4,5,6]);
74  assertTrue(%HasFastSmiElements(a1));
75  assertEquals([1,2,3,4,5,6], a1);
76  a1 = [1,2,3].concat([4,5,6], [7,8,9]);
77  assertTrue(%HasFastSmiElements(a1));
78  assertEquals([1,2,3,4,5,6,7,8,9], a1);
79  a1 = [1.1,2,3].concat([]);
80  assertTrue(%HasFastDoubleElements(a1));
81  assertEquals([1.1,2,3], a1);
82  a1 = [1,2,3].concat([1.1, 2]);
83  assertTrue(%HasFastDoubleElements(a1));
84  assertEquals([1,2,3,1.1,2], a1);
85  a1 = [1.1,2,3].concat([1, 2]);
86  assertTrue(%HasFastDoubleElements(a1));
87  assertEquals([1.1,2,3,1,2], a1);
88  a1 = [1.1,2,3].concat([1.2, 2]);
89  assertTrue(%HasFastDoubleElements(a1));
90  assertEquals([1.1,2,3,1.2,2], a1);
91
92  a1 = [1,2,3].concat([{}]);
93  assertTrue(%HasFastObjectElements(a1));
94  assertEquals([1,2,3,{}], a1);
95  a1 = [1.1,2,3].concat([{}]);
96  assertTrue(%HasFastObjectElements(a1));
97  assertEquals([1.1,2,3,{}], a1);
98  a1 = [{}].concat([1,2,3]);
99  assertTrue(%HasFastObjectElements(a1));
100  assertEquals([{},1,2,3], a1);
101  a1 = [{}].concat([1.1,2,3]);
102  assertTrue(%HasFastObjectElements(a1));
103  assertEquals([{},1.1,2,3], a1);
104
105  // Slice
106  var a2 = [1,2,3];
107  assertTrue(%HasFastSmiElements(a2.slice()));
108  assertTrue(%HasFastSmiElements(a2.slice(1)));
109  assertTrue(%HasFastSmiElements(a2.slice(1, 2)));
110  assertEquals([1,2,3], a2.slice());
111  assertEquals([2,3], a2.slice(1));
112  assertEquals([2], a2.slice(1,2));
113  a2 = [1.1,2,3];
114  assertTrue(%HasFastDoubleElements(a2.slice()));
115  assertTrue(%HasFastDoubleElements(a2.slice(1)));
116  assertTrue(%HasFastDoubleElements(a2.slice(1, 2)));
117  assertEquals([1.1,2,3], a2.slice());
118  assertEquals([2,3], a2.slice(1));
119  assertEquals([2], a2.slice(1,2));
120  a2 = [{},2,3];
121  assertTrue(%HasFastObjectElements(a2.slice()));
122  assertTrue(%HasFastObjectElements(a2.slice(1)));
123  assertTrue(%HasFastObjectElements(a2.slice(1, 2)));
124  assertEquals([{},2,3], a2.slice());
125  assertEquals([2,3], a2.slice(1));
126  assertEquals([2], a2.slice(1,2));
127
128  // Splice
129  var a3 = [1,2,3];
130  var a3r;
131  a3r = a3.splice(0, 0);
132  assertTrue(%HasFastSmiElements(a3r));
133  assertTrue(%HasFastSmiElements(a3));
134  assertEquals([], a3r);
135  assertEquals([1, 2, 3], a3);
136  a3 = [1,2,3];
137  a3r = a3.splice(0, 1);
138  assertTrue(%HasFastSmiElements(a3r));
139  assertTrue(%HasFastSmiElements(a3));
140  assertEquals([1], a3r);
141  assertEquals([2, 3], a3);
142  a3 = [1,2,3];
143  a3r = a3.splice(0, 0, 2);
144  assertTrue(%HasFastSmiElements(a3r));
145  assertTrue(%HasFastSmiElements(a3));
146  assertEquals([], a3r);
147  assertEquals([2, 1, 2, 3], a3);
148  a3 = [1,2,3];
149  a3r = a3.splice(0, 1, 2);
150  assertTrue(%HasFastSmiElements(a3r));
151  assertTrue(%HasFastSmiElements(a3));
152  assertEquals([1], a3r);
153  assertEquals([2, 2, 3], a3);
154
155  a3 = [1.1,2,3];
156  a3r = a3.splice(0, 0);
157  assertTrue(%HasFastDoubleElements(a3r));
158  assertTrue(%HasFastDoubleElements(a3));
159  assertEquals([], a3r);
160  assertEquals([1.1, 2, 3], a3);
161  a3 = [1.1,2,3];
162  a3r = a3.splice(0, 1);
163  assertTrue(%HasFastDoubleElements(a3r));
164  assertTrue(%HasFastDoubleElements(a3));
165  assertEquals([1.1], a3r);
166  assertEquals([2, 3], a3);
167  a3 = [1.1,2,3];
168  a3r = a3.splice(0, 0, 2);
169  // Commented out since handled in js, which takes the best fit.
170  // assertTrue(%HasFastDoubleElements(a3r));
171  assertTrue(%HasFastSmiElements(a3r));
172  assertTrue(%HasFastDoubleElements(a3));
173  assertEquals([], a3r);
174  assertEquals([2, 1.1, 2, 3], a3);
175  a3 = [1.1,2,3];
176  a3r = a3.splice(0, 1, 2);
177  assertTrue(%HasFastDoubleElements(a3r));
178  assertTrue(%HasFastDoubleElements(a3));
179  assertEquals([1.1], a3r);
180  assertEquals([2, 2, 3], a3);
181  a3 = [1.1,2,3];
182  a3r = a3.splice(0, 0, 2.1);
183  // Commented out since handled in js, which takes the best fit.
184  // assertTrue(%HasFastDoubleElements(a3r));
185  assertTrue(%HasFastSmiElements(a3r));
186  assertTrue(%HasFastDoubleElements(a3));
187  assertEquals([], a3r);
188  assertEquals([2.1, 1.1, 2, 3], a3);
189  a3 = [1.1,2,3];
190  a3r = a3.splice(0, 1, 2.2);
191  assertTrue(%HasFastDoubleElements(a3r));
192  assertTrue(%HasFastDoubleElements(a3));
193  assertEquals([1.1], a3r);
194  assertEquals([2.2, 2, 3], a3);
195  a3 = [1,2,3];
196  a3r = a3.splice(0, 0, 2.1);
197  // Commented out since handled in js, which takes the best fit.
198  // assertTrue(%HasFastDoubleElements(a3r));
199  assertTrue(%HasFastSmiElements(a3r));
200  assertTrue(%HasFastDoubleElements(a3));
201  assertEquals([], a3r);
202  assertEquals([2.1, 1, 2, 3], a3);
203  a3 = [1,2,3];
204  a3r = a3.splice(0, 1, 2.2);
205  assertTrue(%HasFastDoubleElements(a3r));
206  assertTrue(%HasFastDoubleElements(a3));
207  assertEquals([1], a3r);
208  assertEquals([2.2, 2, 3], a3);
209
210  a3 = [{},2,3];
211  a3r = a3.splice(0, 0);
212  assertTrue(%HasFastObjectElements(a3r));
213  assertTrue(%HasFastObjectElements(a3));
214  assertEquals([], a3r);
215  assertEquals([{}, 2, 3], a3);
216  a3 = [1,2,{}];
217  a3r = a3.splice(0, 1);
218  assertTrue(%HasFastObjectElements(a3r));
219  assertTrue(%HasFastObjectElements(a3));
220  assertEquals([1], a3r);
221  assertEquals([2, {}], a3);
222  a3 = [1,2,3];
223  a3r = a3.splice(0, 0, {});
224  assertTrue(%HasFastObjectElements(a3r));
225  assertTrue(%HasFastObjectElements(a3));
226  assertEquals([], a3r);
227  assertEquals([{}, 1, 2, 3], a3);
228  a3 = [1,2,3];
229  a3r = a3.splice(0, 1, {});
230  assertTrue(%HasFastObjectElements(a3r));
231  assertTrue(%HasFastObjectElements(a3));
232  assertEquals([1], a3r);
233  assertEquals([{}, 2, 3], a3);
234
235  a3 = [1.1,2,3];
236  a3r = a3.splice(0, 0, {});
237  assertTrue(%HasFastObjectElements(a3r));
238  assertTrue(%HasFastObjectElements(a3));
239  assertEquals([], a3r);
240  assertEquals([{}, 1.1, 2, 3], a3);
241  a3 = [1.1,2,3];
242  a3r = a3.splice(0, 1, {});
243  assertTrue(%HasFastObjectElements(a3r));
244  assertTrue(%HasFastObjectElements(a3));
245  assertEquals([1.1], a3r);
246  assertEquals([{}, 2, 3], a3);
247
248  // Pop
249  var a4 = [1,2,3];
250  assertEquals(3, a4.pop());
251  assertTrue(%HasFastSmiElements(a4));
252  a4 = [1.1,2,3];
253  assertEquals(3, a4.pop());
254  assertTrue(%HasFastDoubleElements(a4));
255  a4 = [{},2,3];
256  assertEquals(3, a4.pop());
257  assertTrue(%HasFastObjectElements(a4));
258
259  // Shift
260  var a4 = [1,2,3];
261  assertEquals(1, a4.shift());
262  assertTrue(%HasFastSmiElements(a4));
263  a4 = [1.1,2,3];
264  assertEquals(1.1, a4.shift());
265  assertTrue(%HasFastDoubleElements(a4));
266  a4 = [{},2,3];
267  assertEquals({}, a4.shift());
268  assertTrue(%HasFastObjectElements(a4));
269
270  // Unshift
271  var a4 = [1,2,3];
272  a4.unshift(1);
273  assertTrue(%HasFastSmiElements(a4));
274  assertEquals([1,1,2,3], a4);
275  a4 = [1,2,3];
276  a4.unshift(1.1);
277  // TODO(verwaest): We'll want to support double unshifting as well.
278  // assertTrue(%HasFastDoubleElements(a4));
279  assertTrue(%HasFastObjectElements(a4));
280  assertEquals([1.1,1,2,3], a4);
281  a4 = [1.1,2,3];
282  a4.unshift(1);
283  // assertTrue(%HasFastDoubleElements(a4));
284  assertTrue(%HasFastObjectElements(a4));
285  assertEquals([1,1.1,2,3], a4);
286  a4 = [{},2,3];
287  a4.unshift(1);
288  assertTrue(%HasFastObjectElements(a4));
289  assertEquals([1,{},2,3], a4);
290  a4 = [{},2,3];
291  a4.unshift(1.1);
292  assertTrue(%HasFastObjectElements(a4));
293  assertEquals([1.1,{},2,3], a4);
294}
295
296for (var i = 0; i < 3; i++) {
297  array_natives_test();
298}
299%OptimizeFunctionOnNextCall(array_natives_test);
300array_natives_test();
301