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(
25'Tests whether eval() works inside statements that read and modify a value.'
26);
27
28function multTest()
29{
30    var x = 1;
31    x *= eval('2');
32    return x == 2;
33}
34
35function divTest()
36{
37    var x = 2;
38    x /= eval('2');
39    return x == 1;
40}
41
42function addTest()
43{
44    var x = 0;
45    x += eval('1');
46    return x == 1;
47}
48
49function subTest()
50{
51    var x = 0;
52    x -= eval('1');
53    return x == -1;
54}
55
56function lshiftTest()
57{
58    var x = 1;
59    x <<= eval('1');
60    return x == 2;
61}
62
63function rshiftTest()
64{
65    var x = 1;
66    x >>= eval('1');
67    return x == 0;
68}
69
70function urshiftTest()
71{
72    var x = 1;
73    x >>>= eval('1');
74    return x == 0;
75}
76
77function andTest()
78{
79    var x = 1;
80    x &= eval('1');
81    return x == 1;
82}
83
84function xorTest()
85{
86    var x = 0;
87    x ^= eval('1');
88    return x == 1;
89}
90
91function orTest()
92{
93    var x = 0;
94    x |= eval('1');
95    return x == 1;
96}
97
98function modTest()
99{
100    var x = 4;
101    x %= eval('3');
102    return x == 1;
103}
104
105function preIncTest()
106{
107    var x = { value: 0 };
108    ++eval('x').value;
109    return x.value == 1;
110}
111
112function preDecTest()
113{
114    var x = { value: 0 };
115    --eval('x').value;
116    return x.value == -1;
117}
118
119function postIncTest()
120{
121    var x = { value: 0 };
122    eval('x').value++;
123    return x.value == 1;
124}
125
126function postDecTest()
127{
128    var x = { value: 0 };
129    eval('x').value--;
130    return x.value == -1;
131}
132
133function primitiveThisTest()
134{
135    // Test that conversion of this is persistant over multiple calls to eval,
136    // even where 'this' is not directly used within the function.
137    eval('this.value = "Seekrit message";');
138    return eval('this.value') === "Seekrit message";
139}
140
141function strictThisTest()
142{
143    // In a strict mode function primitive this values are not converted, so
144    // the property access in the first eval is writing a value to a temporary
145    // object. This throws, per section 8.7.2.
146    "use strict";
147    eval('this.value = "Seekrit message";');
148    return eval('this.value') === undefined;
149}
150
151shouldBeTrue('multTest();');
152shouldBeTrue('divTest();');
153shouldBeTrue('addTest();');
154shouldBeTrue('subTest();');
155shouldBeTrue('lshiftTest();');
156shouldBeTrue('rshiftTest();');
157shouldBeTrue('urshiftTest();');
158shouldBeTrue('andTest();');
159shouldBeTrue('xorTest();');
160shouldBeTrue('orTest();');
161shouldBeTrue('modTest();');
162
163shouldBeTrue('preIncTest();');
164shouldBeTrue('preDecTest();');
165shouldBeTrue('postIncTest();');
166shouldBeTrue('postDecTest();');
167
168shouldBeTrue('primitiveThisTest.call(1);');
169shouldThrow('strictThisTest.call(1);');
170