1// Copyright 2013 the V8 project authors. All rights reserved.
2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1.  Redistributions of source code must retain the above copyright
8//     notice, this list of conditions and the following disclaimer.
9// 2.  Redistributions in binary form must reproduce the above copyright
10//     notice, this list of conditions and the following disclaimer in the
11//     documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24description("KDE JS Test");
25function nonSpeculativeNotInner(argument, o1, o2)
26{
27    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
28    o1 + o2;
29    return !argument;
30}
31function nonSpeculativeNot(argument)
32{
33    return nonSpeculativeNotInner(argument, {}, {});
34}
35
36function nonSpeculativeLessInner(a, b, o1, o2)
37{
38    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
39    o1 + o2;
40    return a < b;
41}
42function nonSpeculativeLess(a, b)
43{
44    return nonSpeculativeLessInner(a, b, {}, {});
45}
46
47function nonSpeculativeLessEqInner(a, b, o1, o2)
48{
49    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
50    o1 + o2;
51    return a <= b;
52}
53function nonSpeculativeLessEq(a, b)
54{
55    return nonSpeculativeLessEqInner(a, b, {}, {});
56}
57
58function nonSpeculativeGreaterInner(a, b, o1, o2)
59{
60    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
61    o1 + o2;
62    return a > b;
63}
64function nonSpeculativeGreater(a, b)
65{
66    return nonSpeculativeGreaterInner(a, b, {}, {});
67}
68
69function nonSpeculativeGreaterEqInner(a, b, o1, o2)
70{
71    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
72    o1 + o2;
73    return a >= b;
74}
75function nonSpeculativeGreaterEq(a, b)
76{
77    return nonSpeculativeGreaterEqInner(a, b, {}, {});
78}
79
80function nonSpeculativeEqualInner(a, b, o1, o2)
81{
82    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
83    o1 + o2;
84    return a == b;
85}
86function nonSpeculativeEqual(a, b)
87{
88    return nonSpeculativeEqualInner(a, b, {}, {});
89}
90
91function nonSpeculativeNotEqualInner(a, b, o1, o2)
92{
93    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
94    o1 + o2;
95    return a != b;
96}
97function nonSpeculativeNotEqual(a, b)
98{
99    return nonSpeculativeNotEqualInner(a, b, {}, {});
100}
101
102function nonSpeculativeStrictEqualInner(a, b, o1, o2)
103{
104    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
105    o1 + o2;
106    return a === b;
107}
108function nonSpeculativeStrictEqual(a, b)
109{
110    return nonSpeculativeStrictEqualInner(a, b, {}, {});
111}
112
113function nonSpeculativeStrictNotEqualInner(a, b, o1, o2)
114{
115    // The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
116    o1 + o2;
117    return a !== b;
118}
119function nonSpeculativeStrictNotEqual(a, b)
120{
121    return nonSpeculativeStrictNotEqualInner(a, b, {}, {});
122}
123
124// operator !
125shouldBeTrue("!undefined");
126shouldBeTrue("!null");
127shouldBeTrue("!!true");
128shouldBeTrue("!false");
129shouldBeTrue("!!1");
130shouldBeTrue("!0");
131shouldBeTrue("!!'a'");
132shouldBeTrue("!''");
133
134shouldBeTrue("nonSpeculativeNot(undefined)");
135shouldBeTrue("nonSpeculativeNot(null)");
136shouldBeTrue("nonSpeculativeNot(!true)");
137shouldBeTrue("nonSpeculativeNot(false)");
138shouldBeTrue("nonSpeculativeNot(!1)");
139shouldBeTrue("nonSpeculativeNot(0)");
140shouldBeTrue("nonSpeculativeNot(!'a')");
141shouldBeTrue("nonSpeculativeNot('')");
142
143// unary plus
144shouldBe("+9", "9");
145shouldBe("var i = 10; +i", "10");
146
147// negation
148shouldBe("-11", "-11");
149shouldBe("var i = 12; -i", "-12");
150
151// increment
152shouldBe("var i = 0; ++i;", "1");
153shouldBe("var i = 0; ++i; i", "1");
154shouldBe("var i = 0; i++;", "0");
155shouldBe("var i = 0; i++; i", "1");
156shouldBe("var i = true; i++", "1");
157shouldBe("var i = true; i++; i", "2");
158
159// decrement
160shouldBe("var i = 0; --i;", "-1");
161shouldBe("var i = 0; --i; i", "-1");
162shouldBe("var i = 0; i--;", "0");
163shouldBe("var i = 0; i--; i", "-1");
164shouldBe("var i = true; i--", "1");
165shouldBe("var i = true; i--; i", "0");
166
167// bitwise operators
168shouldBe("~0", "-1");
169shouldBe("~1", "-2");
170shouldBe("~NaN", "-1");
171shouldBe("~Infinity", "-1");
172shouldBe("~Math.pow(2, 33)", "-1"); // 32 bit overflow
173shouldBe("~(Math.pow(2, 32) + Math.pow(2, 31) + 2)",
174         "2147483645"); // a signedness issue
175shouldBe("~null", "-1");
176shouldBe("3 & 1", "1");
177shouldBe("2 | true", "3");
178shouldBe("'3' ^ 1", "2");
179shouldBe("3^4&5", "7");
180shouldBe("2|4^5", "3");
181
182shouldBe("1 << 2", "4");
183shouldBe("8 >> 1", "4");
184shouldBe("1 >> 2", "0");
185shouldBe("-8 >> 24", "-1");
186shouldBe("8 >>> 2", "2");
187shouldBe("-8 >>> 24", "255");
188shouldBe("(-2200000000 >> 1) << 1", "2094967296");
189shouldBe("Infinity >> 1", "0");
190shouldBe("Infinity << 1", "0");
191shouldBe("Infinity >>> 1", "0");
192shouldBe("NaN >> 1", "0");
193shouldBe("NaN << 1", "0");
194shouldBe("NaN >>> 1", "0");
195shouldBe("8.1 >> 1", "4");
196shouldBe("8.1 << 1", "16");
197shouldBe("8.1 >>> 1", "4");
198shouldBe("8.9 >> 1", "4");
199shouldBe("8.9 << 1", "16");
200shouldBe("8.9 >>> 1", "4");
201shouldBe("Math.pow(2, 32) >> 1", "0");
202shouldBe("Math.pow(2, 32) << 1", "0");
203shouldBe("Math.pow(2, 32) >>> 1", "0");
204
205// Try shifting by variables, to test non-constant-folded cases.
206var one = 1;
207var two = 2;
208var twentyFour = 24;
209
210shouldBe("1 << two", "4");
211shouldBe("8 >> one", "4");
212shouldBe("1 >> two", "0");
213shouldBe("-8 >> twentyFour", "-1");
214shouldBe("8 >>> two", "2");
215shouldBe("-8 >>> twentyFour", "255");
216shouldBe("(-2200000000 >> one) << one", "2094967296");
217shouldBe("Infinity >> one", "0");
218shouldBe("Infinity << one", "0");
219shouldBe("Infinity >>> one", "0");
220shouldBe("NaN >> one", "0");
221shouldBe("NaN << one", "0");
222shouldBe("NaN >>> one", "0");
223shouldBe("888.1 >> one", "444");
224shouldBe("888.1 << one", "1776");
225shouldBe("888.1 >>> one", "444");
226shouldBe("888.9 >> one", "444");
227shouldBe("888.9 << one", "1776");
228shouldBe("888.9 >>> one", "444");
229shouldBe("Math.pow(2, 32) >> one", "0");
230shouldBe("Math.pow(2, 32) << one", "0");
231shouldBe("Math.pow(2, 32) >>> one", "0");
232
233// addition
234shouldBe("1+2", "3");
235shouldBe("'a'+'b'", "'ab'");
236shouldBe("'a'+2", "'a2'");
237shouldBe("'2'+'-1'", "'2-1'");
238shouldBe("true+'a'", "'truea'");
239shouldBe("'a' + null", "'anull'");
240shouldBe("true+1", "2");
241shouldBe("false+null", "0");
242
243// substraction
244shouldBe("1-3", "-2");
245shouldBe("isNaN('a'-3)", "true");
246shouldBe("'3'-'-1'", "4");
247shouldBe("'4'-2", "2");
248shouldBe("true-false", "1");
249shouldBe("false-1", "-1");
250shouldBe("null-true", "-1");
251
252// multiplication
253shouldBe("2 * 3", "6");
254shouldBe("true * 3", "3");
255shouldBe("2 * '3'", "6");
256
257// division
258shouldBe("6 / 4", "1.5");
259//shouldBe("true / false", "Inf");
260shouldBe("'6' / '2'", "3");
261shouldBeTrue("isNaN('x' / 1)");
262shouldBeTrue("isNaN(1 / NaN)");
263shouldBeTrue("isNaN(Infinity / Infinity)");
264shouldBe("Infinity / 0", "Infinity");
265shouldBe("-Infinity / 0", "-Infinity");
266shouldBe("Infinity / 1", "Infinity");
267shouldBe("-Infinity / 1", "-Infinity");
268shouldBeTrue("1 / Infinity == +0");
269shouldBeTrue("1 / -Infinity == -0"); // how to check ?
270shouldBeTrue("isNaN(0/0)");
271shouldBeTrue("0 / 1 === 0");
272shouldBeTrue("0 / -1 === -0"); // how to check ?
273shouldBe("1 / 0", "Infinity");
274shouldBe("-1 / 0", "-Infinity");
275
276// modulo
277shouldBe("6 % 4", "2");
278shouldBe("'-6' % 4", "-2");
279
280shouldBe("2==2", "true");
281shouldBe("1==2", "false");
282
283shouldBe("nonSpeculativeEqual(2,2)", "true");
284shouldBe("nonSpeculativeEqual(1,2)", "false");
285
286shouldBe("1<2", "true");
287shouldBe("1<=2", "true");
288shouldBe("2<1", "false");
289shouldBe("2<=1", "false");
290
291shouldBe("nonSpeculativeLess(1,2)", "true");
292shouldBe("nonSpeculativeLessEq(1,2)", "true");
293shouldBe("nonSpeculativeLess(2,1)", "false");
294shouldBe("nonSpeculativeLessEq(2,1)", "false");
295
296shouldBe("2>1", "true");
297shouldBe("2>=1", "true");
298shouldBe("1>=2", "false");
299shouldBe("1>2", "false");
300
301shouldBe("nonSpeculativeGreater(2,1)", "true");
302shouldBe("nonSpeculativeGreaterEq(2,1)", "true");
303shouldBe("nonSpeculativeGreaterEq(1,2)", "false");
304shouldBe("nonSpeculativeGreater(1,2)", "false");
305
306shouldBeTrue("'abc' == 'abc'");
307shouldBeTrue("'abc' != 'xyz'");
308shouldBeTrue("true == true");
309shouldBeTrue("false == false");
310shouldBeTrue("true != false");
311shouldBeTrue("'a' != null");
312shouldBeTrue("'a' != undefined");
313shouldBeTrue("null == null");
314shouldBeTrue("null == undefined");
315shouldBeTrue("undefined == undefined");
316shouldBeTrue("NaN != NaN");
317shouldBeTrue("true != undefined");
318shouldBeTrue("true != null");
319shouldBeTrue("false != undefined");
320shouldBeTrue("false != null");
321shouldBeTrue("'0' == 0");
322shouldBeTrue("1 == '1'");
323shouldBeTrue("NaN != NaN");
324shouldBeTrue("NaN != 0");
325shouldBeTrue("NaN != undefined");
326shouldBeTrue("true == 1");
327shouldBeTrue("true != 2");
328shouldBeTrue("1 == true");
329shouldBeTrue("false == 0");
330shouldBeTrue("0 == false");
331
332shouldBeTrue("nonSpeculativeEqual('abc', 'abc')");
333shouldBeTrue("nonSpeculativeNotEqual('abc', 'xyz')");
334shouldBeTrue("nonSpeculativeEqual(true, true)");
335shouldBeTrue("nonSpeculativeEqual(false, false)");
336shouldBeTrue("nonSpeculativeNotEqual(true, false)");
337shouldBeTrue("nonSpeculativeNotEqual('a', null)");
338shouldBeTrue("nonSpeculativeNotEqual('a', undefined)");
339shouldBeTrue("nonSpeculativeEqual(null, null)");
340shouldBeTrue("nonSpeculativeEqual(null, undefined)");
341shouldBeTrue("nonSpeculativeEqual(undefined, undefined)");
342shouldBeTrue("nonSpeculativeNotEqual(NaN, NaN)");
343shouldBeTrue("nonSpeculativeNotEqual(true, undefined)");
344shouldBeTrue("nonSpeculativeNotEqual(true, null)");
345shouldBeTrue("nonSpeculativeNotEqual(false, undefined)");
346shouldBeTrue("nonSpeculativeNotEqual(false, null)");
347shouldBeTrue("nonSpeculativeEqual('0', 0)");
348shouldBeTrue("nonSpeculativeEqual(1, '1')");
349shouldBeTrue("nonSpeculativeNotEqual(NaN, NaN)");
350shouldBeTrue("nonSpeculativeNotEqual(NaN, 0)");
351shouldBeTrue("nonSpeculativeNotEqual(NaN, undefined)");
352shouldBeTrue("nonSpeculativeEqual(true, 1)");
353shouldBeTrue("nonSpeculativeNotEqual(true, 2)");
354shouldBeTrue("nonSpeculativeEqual(1, true)");
355shouldBeTrue("nonSpeculativeEqual(false, 0)");
356shouldBeTrue("nonSpeculativeEqual(0, false)");
357
358shouldBe("'abc' < 'abx'", "true");
359shouldBe("'abc' < 'abcd'", "true");
360shouldBe("'abc' < 'abc'", "false");
361shouldBe("'abcd' < 'abcd'", "false");
362shouldBe("'abx' < 'abc'", "false");
363
364shouldBe("nonSpeculativeLess('abc', 'abx')", "true");
365shouldBe("nonSpeculativeLess('abc', 'abcd')", "true");
366shouldBe("nonSpeculativeLess('abc', 'abc')", "false");
367shouldBe("nonSpeculativeLess('abcd', 'abcd')", "false");
368shouldBe("nonSpeculativeLess('abx', 'abc')", "false");
369
370shouldBe("'abc' <= 'abc'", "true");
371shouldBe("'abc' <= 'abx'", "true");
372shouldBe("'abx' <= 'abc'", "false");
373shouldBe("'abcd' <= 'abc'", "false");
374shouldBe("'abc' <= 'abcd'", "true");
375
376shouldBe("nonSpeculativeLessEq('abc', 'abc')", "true");
377shouldBe("nonSpeculativeLessEq('abc', 'abx')", "true");
378shouldBe("nonSpeculativeLessEq('abx', 'abc')", "false");
379shouldBe("nonSpeculativeLessEq('abcd', 'abc')", "false");
380shouldBe("nonSpeculativeLessEq('abc', 'abcd')", "true");
381
382shouldBe("'abc' > 'abx'", "false");
383shouldBe("'abc' > 'abc'", "false");
384shouldBe("'abcd' > 'abc'", "true");
385shouldBe("'abx' > 'abc'", "true");
386shouldBe("'abc' > 'abcd'", "false");
387
388shouldBe("nonSpeculativeGreater('abc', 'abx')", "false");
389shouldBe("nonSpeculativeGreater('abc', 'abc')", "false");
390shouldBe("nonSpeculativeGreater('abcd', 'abc')", "true");
391shouldBe("nonSpeculativeGreater('abx', 'abc')", "true");
392shouldBe("nonSpeculativeGreater('abc', 'abcd')", "false");
393
394shouldBe("'abc' >= 'abc'", "true");
395shouldBe("'abcd' >= 'abc'", "true");
396shouldBe("'abx' >= 'abc'", "true");
397shouldBe("'abc' >= 'abx'", "false");
398shouldBe("'abc' >= 'abx'", "false");
399shouldBe("'abc' >= 'abcd'", "false");
400
401shouldBe("nonSpeculativeGreaterEq('abc', 'abc')", "true");
402shouldBe("nonSpeculativeGreaterEq('abcd', 'abc')", "true");
403shouldBe("nonSpeculativeGreaterEq('abx', 'abc')", "true");
404shouldBe("nonSpeculativeGreaterEq('abc', 'abx')", "false");
405shouldBe("nonSpeculativeGreaterEq('abc', 'abx')", "false");
406shouldBe("nonSpeculativeGreaterEq('abc', 'abcd')", "false");
407
408// mixed strings and numbers - results validated in NS+moz+IE5
409shouldBeFalse("'abc' <= 0"); // #35246
410shouldBeTrue("'' <= 0");
411shouldBeTrue("' ' <= 0");
412shouldBeTrue("null <= 0");
413shouldBeFalse("0 <= 'abc'");
414shouldBeTrue("0 <= ''");
415shouldBeTrue("0 <= null");
416shouldBeTrue("null <= null");
417shouldBeTrue("6 < '52'");
418shouldBeTrue("6 < '72'"); // #36087
419shouldBeFalse("NaN < 0");
420shouldBeFalse("NaN <= 0");
421shouldBeFalse("NaN > 0");
422shouldBeFalse("NaN >= 0");
423
424shouldBeFalse("nonSpeculativeLessEq('abc', 0)"); // #35246
425shouldBeTrue("nonSpeculativeLessEq('', 0)");
426shouldBeTrue("nonSpeculativeLessEq(' ', 0)");
427shouldBeTrue("nonSpeculativeLessEq(null, 0)");
428shouldBeFalse("nonSpeculativeLessEq(0, 'abc')");
429shouldBeTrue("nonSpeculativeLessEq(0, '')");
430shouldBeTrue("nonSpeculativeLessEq(0, null)");
431shouldBeTrue("nonSpeculativeLessEq(null, null)");
432shouldBeTrue("nonSpeculativeLess(6, '52')");
433shouldBeTrue("nonSpeculativeLess(6, '72')"); // #36087
434shouldBeFalse("nonSpeculativeLess(NaN, 0)");
435shouldBeFalse("nonSpeculativeLessEq(NaN, 0)");
436shouldBeFalse("nonSpeculativeGreater(NaN, 0)");
437shouldBeFalse("nonSpeculativeGreaterEq(NaN, 0)");
438
439// strict comparison ===
440shouldBeFalse("0 === false");
441//shouldBe("undefined === undefined", "true"); // aborts in IE5 (undefined is not defined ;)
442shouldBeTrue("null === null");
443shouldBeFalse("NaN === NaN");
444shouldBeTrue("0.0 === 0");
445shouldBeTrue("'abc' === 'abc'");
446shouldBeFalse("'a' === 'x'");
447shouldBeFalse("1 === '1'");
448shouldBeFalse("'1' === 1");
449shouldBeTrue("true === true");
450shouldBeTrue("false === false");
451shouldBeFalse("true === false");
452shouldBeTrue("Math === Math");
453shouldBeFalse("Math === Boolean");
454shouldBeTrue("Infinity === Infinity");
455
456// strict comparison ===
457shouldBeFalse("nonSpeculativeStrictEqual(0, false)");
458//shouldBe("undefined === undefined", "true"); // aborts in IE5 (undefined is not defined ;)
459shouldBeTrue("nonSpeculativeStrictEqual(null, null)");
460shouldBeFalse("nonSpeculativeStrictEqual(NaN, NaN)");
461shouldBeTrue("nonSpeculativeStrictEqual(0.0, 0)");
462shouldBeTrue("nonSpeculativeStrictEqual('abc', 'abc')");
463shouldBeFalse("nonSpeculativeStrictEqual('a', 'x')");
464shouldBeFalse("nonSpeculativeStrictEqual(1, '1')");
465shouldBeFalse("nonSpeculativeStrictEqual('1', 1)");
466shouldBeTrue("nonSpeculativeStrictEqual(true, true)");
467shouldBeTrue("nonSpeculativeStrictEqual(false, false)");
468shouldBeFalse("nonSpeculativeStrictEqual(true, false)");
469shouldBeTrue("nonSpeculativeStrictEqual(Math, Math)");
470shouldBeFalse("nonSpeculativeStrictEqual(Math, Boolean)");
471shouldBeTrue("nonSpeculativeStrictEqual(Infinity, Infinity)");
472
473// !==
474shouldBe("0 !== 0", "false");
475shouldBe("0 !== 1", "true");
476
477// !==
478shouldBe("nonSpeculativeStrictNotEqual(0, 0)", "false");
479shouldBe("nonSpeculativeStrictNotEqual(0, 1)", "true");
480
481shouldBe("typeof undefined", "'undefined'");
482shouldBe("typeof null", "'object'");
483shouldBe("typeof true", "'boolean'");
484shouldBe("typeof false", "'boolean'");
485shouldBe("typeof 1", "'number'");
486shouldBe("typeof 'a'", "'string'");
487shouldBe("typeof shouldBe", "'function'");
488shouldBe("typeof Number.NaN", "'number'");
489
490shouldBe("11 && 22", "22");
491shouldBe("null && true", "null");
492shouldBe("11 || 22", "11");
493shouldBe("null || 'a'", "'a'");
494
495shouldBeUndefined("void 1");
496
497shouldBeTrue("1 in [1, 2]");
498shouldBeFalse("3 in [1, 2]");
499shouldBeTrue("'a' in { a:1, b:2 }");
500
501// instanceof
502// Those 2 lines don't parse in Netscape...
503shouldBe("(new Boolean()) instanceof Boolean", "true");
504shouldBe("(new Boolean()) instanceof Number", "false");
505