blob: 58d61af356743ef31d8c4055b1fc8b5ee6b2f3d2 [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 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
29var should_throw_on_null_and_undefined =
30 [Object.prototype.toLocaleString,
31 Object.prototype.valueOf,
32 Object.prototype.hasOwnProperty,
33 Object.prototype.isPrototypeOf,
34 Object.prototype.propertyIsEnumerable,
35 Array.prototype.concat,
36 Array.prototype.join,
37 Array.prototype.pop,
38 Array.prototype.push,
39 Array.prototype.reverse,
40 Array.prototype.shift,
41 Array.prototype.slice,
42 Array.prototype.sort,
43 Array.prototype.splice,
44 Array.prototype.unshift,
45 Array.prototype.indexOf,
46 Array.prototype.lastIndexOf,
47 Array.prototype.every,
48 Array.prototype.some,
49 Array.prototype.forEach,
50 Array.prototype.map,
51 Array.prototype.filter,
52 Array.prototype.reduce,
53 Array.prototype.reduceRight,
54 String.prototype.charAt,
55 String.prototype.charCodeAt,
56 String.prototype.concat,
57 String.prototype.indexOf,
58 String.prototype.lastIndexOf,
59 String.prototype.localeCompare,
60 String.prototype.match,
61 String.prototype.replace,
62 String.prototype.search,
63 String.prototype.slice,
64 String.prototype.split,
65 String.prototype.substring,
66 String.prototype.toLowerCase,
67 String.prototype.toLocaleLowerCase,
68 String.prototype.toUpperCase,
69 String.prototype.toLocaleUpperCase,
70 String.prototype.trim,
71 Number.prototype.toLocaleString,
72 Error.prototype.toString];
73
74// Non generic natives do not work on any input other than the specific
75// type, but since this change will allow call to be invoked with undefined
76// or null as this we still explicitly test that we throw on these here.
77var non_generic =
78 [Array.prototype.toString,
79 Array.prototype.toLocaleString,
80 Function.prototype.toString,
81 Function.prototype.call,
82 Function.prototype.apply,
83 String.prototype.toString,
84 String.prototype.valueOf,
85 Boolean.prototype.toString,
86 Boolean.prototype.valueOf,
87 Number.prototype.toString,
88 Number.prototype.valueOf,
89 Number.prototype.toFixed,
90 Number.prototype.toExponential,
91 Number.prototype.toPrecision,
92 Date.prototype.toString,
93 Date.prototype.toDateString,
94 Date.prototype.toTimeString,
95 Date.prototype.toLocaleString,
96 Date.prototype.toLocaleDateString,
97 Date.prototype.toLocaleTimeString,
98 Date.prototype.valueOf,
99 Date.prototype.getTime,
100 Date.prototype.getFullYear,
101 Date.prototype.getUTCFullYear,
102 Date.prototype.getMonth,
103 Date.prototype.getUTCMonth,
104 Date.prototype.getDate,
105 Date.prototype.getUTCDate,
106 Date.prototype.getDay,
107 Date.prototype.getUTCDay,
108 Date.prototype.getHours,
109 Date.prototype.getUTCHours,
110 Date.prototype.getMinutes,
111 Date.prototype.getUTCMinutes,
112 Date.prototype.getSeconds,
113 Date.prototype.getUTCSeconds,
114 Date.prototype.getMilliseconds,
115 Date.prototype.getUTCMilliseconds,
116 Date.prototype.getTimezoneOffset,
117 Date.prototype.setTime,
118 Date.prototype.setMilliseconds,
119 Date.prototype.setUTCMilliseconds,
120 Date.prototype.setSeconds,
121 Date.prototype.setUTCSeconds,
122 Date.prototype.setMinutes,
123 Date.prototype.setUTCMinutes,
124 Date.prototype.setHours,
125 Date.prototype.setUTCHours,
126 Date.prototype.setDate,
127 Date.prototype.setUTCDate,
128 Date.prototype.setMonth,
129 Date.prototype.setUTCMonth,
130 Date.prototype.setFullYear,
131 Date.prototype.setUTCFullYear,
132 Date.prototype.toUTCString,
133 Date.prototype.toISOString,
134 Date.prototype.toJSON,
135 RegExp.prototype.exec,
136 RegExp.prototype.test,
137 RegExp.prototype.toString];
138
139
140// Mapping functions.
141var mapping_functions =
142 [Array.prototype.every,
143 Array.prototype.some,
144 Array.prototype.forEach,
145 Array.prototype.map,
146 Array.prototype.filter];
147
148// Reduce functions.
149var reducing_functions =
150 [Array.prototype.reduce,
151 Array.prototype.reduceRight];
152
153// Test that all natives using the ToObject call throw the right exception.
154for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
155 // Sanity check that all functions are correct
156 assertEquals(typeof(should_throw_on_null_and_undefined[i]), "function");
157
158 try {
159 // We call all functions with no parameters, which means that essential
160 // parameters will have the undefined value.
161 // The test for whether the "this" value is null or undefined is always
162 // performed before access to the other parameters, so even if the
163 // undefined value is an invalid argument value, it mustn't change
164 // the result of the test.
165 should_throw_on_null_and_undefined[i].call(null);
166 assertUnreachable();
167 } catch (e) {
168 assertTrue("called_on_null_or_undefined" == e.type ||
169 "null_to_object" == e.type);
170 }
171
172 try {
173 should_throw_on_null_and_undefined[i].call(undefined);
174 assertUnreachable();
175 } catch (e) {
176 assertTrue("called_on_null_or_undefined" == e.type ||
177 "null_to_object" == e.type);
178 }
179
180 try {
181 should_throw_on_null_and_undefined[i].apply(null);
182 assertUnreachable();
183 } catch (e) {
184 assertTrue("called_on_null_or_undefined" == e.type ||
185 "null_to_object" == e.type);
186 }
187
188 try {
189 should_throw_on_null_and_undefined[i].apply(undefined);
190 assertUnreachable();
191 } catch (e) {
192 assertTrue("called_on_null_or_undefined" == e.type ||
193 "null_to_object" == e.type);
194 }
195}
196
197// Test that all natives that are non generic throw on null and undefined.
198for (var i = 0; i < non_generic.length; i++) {
199 // Sanity check that all functions are correct
200 assertEquals(typeof(non_generic[i]), "function");
201 try {
202 non_generic[i].call(null);
203 assertUnreachable();
204 } catch (e) {
205 assertTrue(e instanceof TypeError);
206 }
207
208 try {
209 non_generic[i].call(null);
210 assertUnreachable();
211 } catch (e) {
212 assertTrue(e instanceof TypeError);
213 }
214
215 try {
216 non_generic[i].apply(null);
217 assertUnreachable();
218 } catch (e) {
219 assertTrue(e instanceof TypeError);
220 }
221
222 try {
223 non_generic[i].apply(null);
224 assertUnreachable();
225 } catch (e) {
226 assertTrue(e instanceof TypeError);
227 }
228}
229
230
231// Test that we still throw when calling with thisArg null or undefined
232// through an array mapping function.
233var array = [1,2,3,4,5];
234for (var j = 0; j < mapping_functions.length; j++) {
235 for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
236 try {
237 mapping_functions[j].call(array,
238 should_throw_on_null_and_undefined[i],
239 null);
240 assertUnreachable();
241 } catch (e) {
242 assertTrue("called_on_null_or_undefined" == e.type ||
243 "null_to_object" == e.type);
244 }
245
246 try {
247 mapping_functions[j].call(array,
248 should_throw_on_null_and_undefined[i],
249 undefined);
250 assertUnreachable();
251 } catch (e) {
252 assertTrue("called_on_null_or_undefined" == e.type ||
253 "null_to_object" == e.type);
254 }
255 }
256}
257
258for (var j = 0; j < mapping_functions.length; j++) {
259 for (var i = 0; i < non_generic.length; i++) {
260 try {
261 mapping_functions[j].call(array,
262 non_generic[i],
263 null);
264 assertUnreachable();
265 } catch (e) {
266 assertTrue(e instanceof TypeError);
267 }
268
269 try {
270 mapping_functions[j].call(array,
271 non_generic[i],
272 undefined);
273 assertUnreachable();
274 } catch (e) {
275 assertTrue(e instanceof TypeError);
276 }
277 }
278}
279
280
281// Reduce functions do a call with null as this argument.
282for (var j = 0; j < reducing_functions.length; j++) {
283 for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
284 try {
285 reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
286 assertUnreachable();
287 } catch (e) {
288 assertTrue("called_on_null_or_undefined" == e.type ||
289 "null_to_object" == e.type);
290 }
291
292 try {
293 reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
294 assertUnreachable();
295 } catch (e) {
296 assertTrue("called_on_null_or_undefined" == e.type ||
297 "null_to_object" == e.type);
298 }
299 }
300}
301
302for (var j = 0; j < reducing_functions.length; j++) {
303 for (var i = 0; i < non_generic.length; i++) {
304 try {
305 reducing_functions[j].call(array, non_generic[i]);
306 assertUnreachable();
307 } catch (e) {
308 assertTrue(e instanceof TypeError);
309 }
310
311 try {
312 reducing_functions[j].call(array, non_generic[i]);
313 assertUnreachable();
314 } catch (e) {
315 assertTrue(e instanceof TypeError);
316 }
317 }
318}
319
320
321// Object.prototype.toString()
322assertEquals(Object.prototype.toString.call(null),
323 '[object Null]')
324
325assertEquals(Object.prototype.toString.call(undefined),
326 '[object Undefined]')