blob: 9d82965f1d2b9dc7d97d7e94b872f51909e39a93 [file] [log] [blame]
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001// Copyright 2010 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// A test for keyed call ICs.
29
30var toStringName = 'toString';
31var global = this;
32
33function globalFunction1() {
34 return 'function1';
35}
36
37function globalFunction2() {
38 return 'function2';
39}
40
41assertEquals("[object global]", this[toStringName]());
42assertEquals("[object global]", global[toStringName]());
43
44function testGlobals() {
45 assertEquals("[object global]", this[toStringName]());
46 assertEquals("[object global]", global[toStringName]());
47}
48
49testGlobals();
50
51
52function F() {}
53
54F.prototype.one = function() {return 'one'; }
55F.prototype.two = function() {return 'two'; }
56F.prototype.three = function() {return 'three'; }
57
58var keys =
59 ['one', 'one', 'one', 'one', 'two', 'two', 'one', 'three', 'one', 'two'];
60
61function testKeyTransitions() {
62 var i, key, result, message;
63
64 var f = new F();
65
66 // Custom call generators
67 var array = [];
68 for (i = 0; i != 10; i++) {
69 key = (i < 8) ? 'push' : 'pop';
70 array[key](i);
71 }
72
73 assertEquals(6, array.length);
74 for (i = 0; i != array.length; i++) {
75 assertEquals(i, array[i]);
76 }
77
78 for (i = 0; i != 10; i++) {
79 key = (i < 3) ? 'pop' : 'push';
80 array[key](i);
81 }
82
83 assertEquals(10, array.length);
84 for (i = 0; i != array.length; i++) {
85 assertEquals(i, array[i]);
86 }
87
88 var string = 'ABCDEFGHIJ';
89 for (i = 0; i != 10; i++) {
90 key = ((i < 5) ? 'charAt' : 'charCodeAt');
91 result = string[key](i);
92 message = '\'' + string + '\'[\'' + key + '\'](' + i + ')';
93 if (i < 5) {
94 assertEquals(string.charAt(i), result, message);
95 } else {
96 assertEquals(string.charCodeAt(i), result, message);
97 }
98 }
99
100 for (i = 0; i != 10; i++) {
101 key = ((i < 5) ? 'charCodeAt' : 'charAt');
102 result = string[key](i);
103 message = '\'' + string + '\'[\'' + key + '\'](' + i + ')';
104 if (i < 5) {
105 assertEquals(string.charCodeAt(i), result, message);
106 } else {
107 assertEquals(string.charAt(i), result, message);
108 }
109 }
110
111 // Function is a constant property
112 key = 'one';
113 for (i = 0; i != 10; i++) {
114 assertEquals(key, f[key]());
115 if (i == 5) {
116 key = 'two'; // the name change should case a miss
117 }
118 }
119
120 // Function is a fast property
121 f.field = function() { return 'field'; }
122 key = 'field';
123 for (i = 0; i != 10; i++) {
124 assertEquals(key, f[key]());
125 if (i == 5) {
126 key = 'two'; // the name change should case a miss
127 }
128 }
129
130 // Calling on slow case object
131 f.prop = 0;
132 delete f.prop; // force the object to the slow case
133 f.four = function() { return 'four'; }
134 f.five = function() { return 'five'; }
135
136 key = 'four';
137 for (i = 0; i != 10; i++) {
138 assertEquals(key, f[key]());
139 if (i == 5) {
140 key = 'five';
141 }
142 }
143
144 // Calling on global object
145 key = 'globalFunction1';
146 var expect = 'function1';
147 for (i = 0; i != 10; i++) {
148 assertEquals(expect, global[key]());
149 if (i == 5) {
150 key = 'globalFunction2';
151 expect = 'function2';
152 }
153 }
154}
155
156testKeyTransitions();
157
158function testTypeTransitions() {
159 var f = new F();
160 var s = '';
161 var m = 'one';
162 var i;
163
164 s = '';
165 for (i = 0; i != 10; i++) {
166 if (i == 5) { F.prototype.one = function() { return '1'; } }
167 s += f[m]();
168 }
169 assertEquals("oneoneoneoneone11111", s);
170
171 s = '';
172 for (i = 0; i != 10; i++) {
173 if (i == 5) { f.__proto__ = { one: function() { return 'I'; } } }
174 s += f[m]();
175 }
176 assertEquals("11111IIIII", s);
177
178 s = '';
179 for (i = 0; i != 10; i++) {
180 if (i == 5) { f.one = function() { return 'ONE'; } }
181 s += f[m]();
182 }
183 assertEquals("IIIIIONEONEONEONEONE", s);
184
185 m = 'toString';
186
187 s = '';
188 var obj = { toString: function() { return '2'; } };
189 for (i = 0; i != 10; i++) {
190 if (i == 5) { obj = "TWO"; }
191 s += obj[m]();
192 }
193 assertEquals("22222TWOTWOTWOTWOTWO", s);
194
195 s = '';
196 obj = { toString: function() { return 'ONE'; } };
197 m = 'toString';
198 for (i = 0; i != 10; i++) {
199 if (i == 5) { obj = 1; }
200 s += obj[m]();
201 }
202 assertEquals("ONEONEONEONEONE11111", s);
203}
204
205testTypeTransitions();