• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "jerryscript.h"
17 
18 #include "test-common.h"
19 
20 #define T(op, lhs, rhs, res) \
21   { op, lhs, rhs, res }
22 
23 #define T_NAN(op, lhs, rhs) \
24   { op, lhs, rhs }
25 
26 #define T_ERR(op, lsh, rhs) \
27   T_NAN (op, lsh, rhs)
28 
29 #define T_ARI(lhs, rhs) \
30   T_NAN (JERRY_BIN_OP_SUB, lhs, rhs), \
31   T_NAN (JERRY_BIN_OP_MUL, lhs, rhs), \
32   T_NAN (JERRY_BIN_OP_DIV, lhs, rhs), \
33   T_NAN (JERRY_BIN_OP_REM, lhs, rhs)
34 
35 typedef struct
36 {
37   jerry_binary_operation_t op;
38   jerry_value_t lhs;
39   jerry_value_t rhs;
40   jerry_value_t expected;
41 } test_entry_t;
42 
43 typedef struct
44 {
45   jerry_binary_operation_t op;
46   jerry_value_t lhs;
47   jerry_value_t rhs;
48 } test_nan_entry_t;
49 
50 typedef test_nan_entry_t test_error_entry_t;
51 
52 int
main(void)53 main (void)
54 {
55   TEST_INIT ();
56 
57   jerry_init (JERRY_INIT_EMPTY);
58 
59   jerry_value_t obj1 = jerry_eval ((const jerry_char_t *) "o={x:1};o", 9, JERRY_PARSE_NO_OPTS);
60   jerry_value_t obj2 = jerry_eval ((const jerry_char_t *) "o={x:1};o", 9, JERRY_PARSE_NO_OPTS);
61   jerry_value_t err1 = jerry_create_error (JERRY_ERROR_SYNTAX, (const jerry_char_t *) "error");
62 
63   test_nan_entry_t test_nans[] =
64   {
65     /* Testing addition (+) */
66     T_NAN (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_undefined ()),
67     T_NAN (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_create_undefined ()),
68     T_NAN (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_create_null ()),
69 
70     /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
71     T_ARI (jerry_create_number (3.1), jerry_create_undefined ()),
72     T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_string ((const jerry_char_t *) "bar")),
73     T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_undefined ()),
74     T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_null ()),
75     T_ARI (jerry_create_string ((const jerry_char_t *) "foo"), jerry_create_number (5.0)),
76     T_ARI (jerry_create_undefined (), jerry_create_string ((const jerry_char_t *) "foo")),
77     T_ARI (jerry_create_null (), jerry_create_string ((const jerry_char_t *) "foo")),
78     T_ARI (jerry_create_number (5.0), jerry_create_string ((const jerry_char_t *) "foo")),
79     T_ARI (jerry_create_undefined (), jerry_create_undefined ()),
80     T_ARI (jerry_create_undefined (), jerry_create_null ()),
81     T_ARI (jerry_create_null (), jerry_create_undefined ()),
82     T_ARI (jerry_acquire_value (obj1), jerry_acquire_value (obj1)),
83     T_ARI (jerry_acquire_value (obj1), jerry_acquire_value (obj2)),
84     T_ARI (jerry_acquire_value (obj2), jerry_acquire_value (obj1)),
85     T_ARI (jerry_acquire_value (obj2), jerry_create_undefined ()),
86     T_ARI (jerry_acquire_value (obj1), jerry_create_string ((const jerry_char_t *) "foo")),
87     T_ARI (jerry_acquire_value (obj1), jerry_create_null ()),
88     T_ARI (jerry_acquire_value (obj1), jerry_create_boolean (true)),
89     T_ARI (jerry_acquire_value (obj1), jerry_create_boolean (false)),
90     T_ARI (jerry_acquire_value (obj1), jerry_create_number (5.0)),
91 
92     /* Testing division (/) */
93     T_NAN (JERRY_BIN_OP_DIV, jerry_create_boolean (false), jerry_create_boolean (false)),
94     T_NAN (JERRY_BIN_OP_DIV, jerry_create_number (0.0), jerry_create_number (0.0)),
95     T_NAN (JERRY_BIN_OP_DIV, jerry_create_null (), jerry_create_null ()),
96 
97     /* Testing remainder (%) */
98     T_NAN (JERRY_BIN_OP_REM, jerry_create_boolean (true), jerry_create_boolean (false)),
99     T_NAN (JERRY_BIN_OP_REM, jerry_create_boolean (false), jerry_create_boolean (false)),
100     T_NAN (JERRY_BIN_OP_REM, jerry_create_number (0.0), jerry_create_number (0.0)),
101     T_NAN (JERRY_BIN_OP_REM, jerry_create_null (), jerry_create_null ()),
102   };
103 
104   for (uint32_t idx = 0; idx < sizeof (test_nans) / sizeof (test_nan_entry_t); idx++)
105   {
106     jerry_value_t result = jerry_binary_operation (test_nans[idx].op, test_nans[idx].lhs, test_nans[idx].rhs);
107     TEST_ASSERT (jerry_value_is_number (result));
108 
109     double num = jerry_get_number_value (result);
110 
111     TEST_ASSERT (num != num);
112 
113     jerry_release_value (test_nans[idx].lhs);
114     jerry_release_value (test_nans[idx].rhs);
115     jerry_release_value (result);
116   }
117 
118   test_entry_t tests[] =
119   {
120     /* Testing addition (+) */
121     T (JERRY_BIN_OP_ADD, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (10.0)),
122     T (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (13.1)),
123     T (JERRY_BIN_OP_ADD, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (4.1)),
124     T (JERRY_BIN_OP_ADD,
125        jerry_create_string ((const jerry_char_t *) "foo"),
126        jerry_create_string ((const jerry_char_t *) "bar"),
127        jerry_create_string ((const jerry_char_t *) "foobar")),
128     T (JERRY_BIN_OP_ADD,
129        jerry_create_string ((const jerry_char_t *) "foo"),
130        jerry_create_undefined (),
131        jerry_create_string ((const jerry_char_t *) "fooundefined")),
132     T (JERRY_BIN_OP_ADD,
133        jerry_create_string ((const jerry_char_t *) "foo"),
134        jerry_create_null (),
135        jerry_create_string ((const jerry_char_t *) "foonull")),
136     T (JERRY_BIN_OP_ADD,
137        jerry_create_string ((const jerry_char_t *) "foo"),
138        jerry_create_number (5.0),
139        jerry_create_string ((const jerry_char_t *) "foo5")),
140 
141     T (JERRY_BIN_OP_ADD, jerry_create_null (), jerry_create_null (), jerry_create_number (0.0)),
142     T (JERRY_BIN_OP_ADD, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (2.0)),
143     T (JERRY_BIN_OP_ADD, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (1.0)),
144     T (JERRY_BIN_OP_ADD, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (1.0)),
145     T (JERRY_BIN_OP_ADD, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
146     T (JERRY_BIN_OP_ADD,
147        jerry_acquire_value (obj1),
148        jerry_acquire_value (obj1),
149        jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
150     T (JERRY_BIN_OP_ADD,
151        jerry_acquire_value (obj1),
152        jerry_acquire_value (obj2),
153        jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
154     T (JERRY_BIN_OP_ADD,
155        jerry_acquire_value (obj2),
156        jerry_acquire_value (obj1),
157        jerry_create_string ((const jerry_char_t *) "[object Object][object Object]")),
158     T (JERRY_BIN_OP_ADD,
159        jerry_acquire_value (obj1),
160        jerry_create_null (),
161        jerry_create_string ((const jerry_char_t *) "[object Object]null")),
162     T (JERRY_BIN_OP_ADD,
163        jerry_acquire_value (obj1),
164        jerry_create_undefined (),
165        jerry_create_string ((const jerry_char_t *) "[object Object]undefined")),
166     T (JERRY_BIN_OP_ADD,
167        jerry_acquire_value (obj1),
168        jerry_create_boolean (true),
169        jerry_create_string ((const jerry_char_t *) "[object Object]true")),
170     T (JERRY_BIN_OP_ADD,
171        jerry_acquire_value (obj1),
172        jerry_create_boolean (false),
173        jerry_create_string ((const jerry_char_t *) "[object Object]false")),
174     T (JERRY_BIN_OP_ADD,
175        jerry_acquire_value (obj1),
176        jerry_create_number (5.0),
177        jerry_create_string ((const jerry_char_t *) "[object Object]5")),
178     T (JERRY_BIN_OP_ADD,
179        jerry_acquire_value (obj1),
180        jerry_create_string ((const jerry_char_t *) "foo"),
181        jerry_create_string ((const jerry_char_t *) "[object Object]foo")),
182 
183     /* Testing subtraction (-) */
184     T (JERRY_BIN_OP_SUB, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (0.0)),
185     T (JERRY_BIN_OP_SUB, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (-6.9)),
186     T (JERRY_BIN_OP_SUB, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (2.1)),
187     T (JERRY_BIN_OP_SUB, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (0.0)),
188     T (JERRY_BIN_OP_SUB, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (1.0)),
189     T (JERRY_BIN_OP_SUB, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (-1.0)),
190     T (JERRY_BIN_OP_SUB, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
191     T (JERRY_BIN_OP_SUB, jerry_create_null (), jerry_create_null (), jerry_create_number (-0.0)),
192 
193     /* Testing multiplication (*) */
194     T (JERRY_BIN_OP_MUL, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (25.0)),
195     T (JERRY_BIN_OP_MUL, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (31)),
196     T (JERRY_BIN_OP_MUL, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (3.1)),
197     T (JERRY_BIN_OP_MUL, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (1.0)),
198     T (JERRY_BIN_OP_MUL, jerry_create_boolean (true), jerry_create_boolean (false), jerry_create_number (0.0)),
199     T (JERRY_BIN_OP_MUL, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
200     T (JERRY_BIN_OP_MUL, jerry_create_boolean (false), jerry_create_boolean (false), jerry_create_number (0.0)),
201     T (JERRY_BIN_OP_MUL, jerry_create_null (), jerry_create_null (), jerry_create_number (0.0)),
202 
203     /* Testing division (/) */
204     T (JERRY_BIN_OP_DIV, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (1.0)),
205     T (JERRY_BIN_OP_DIV, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (0.31)),
206     T (JERRY_BIN_OP_DIV, jerry_create_number (3.1), jerry_create_boolean (true), jerry_create_number (3.1)),
207     T (JERRY_BIN_OP_DIV, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (1.0)),
208     T (JERRY_BIN_OP_DIV,
209        jerry_create_boolean (true),
210        jerry_create_boolean (false),
211        jerry_create_number_infinity (false)),
212     T (JERRY_BIN_OP_DIV, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
213 
214     /* Testing remainder (%) */
215     T (JERRY_BIN_OP_REM, jerry_create_number (5.0), jerry_create_number (5.0), jerry_create_number (0.0)),
216     T (JERRY_BIN_OP_REM, jerry_create_number (5.0), jerry_create_number (2.0), jerry_create_number (1.0)),
217     T (JERRY_BIN_OP_REM, jerry_create_number (3.1), jerry_create_number (10), jerry_create_number (3.1)),
218     T (JERRY_BIN_OP_REM,
219        jerry_create_number (3.1),
220        jerry_create_boolean (true),
221        jerry_create_number (0.10000000000000009)),
222     T (JERRY_BIN_OP_REM, jerry_create_boolean (true), jerry_create_boolean (true), jerry_create_number (0.0)),
223     T (JERRY_BIN_OP_REM, jerry_create_boolean (false), jerry_create_boolean (true), jerry_create_number (0.0)),
224 
225   };
226 
227   for (uint32_t idx = 0; idx < sizeof (tests) / sizeof (test_entry_t); idx++)
228   {
229     jerry_value_t result = jerry_binary_operation (tests[idx].op, tests[idx].lhs, tests[idx].rhs);
230     TEST_ASSERT (!jerry_value_is_error (result));
231 
232     jerry_value_t equals = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL, result, tests[idx].expected);
233     TEST_ASSERT (jerry_value_is_boolean (equals) && jerry_get_boolean_value (equals));
234     jerry_release_value (equals);
235 
236     jerry_release_value (tests[idx].lhs);
237     jerry_release_value (tests[idx].rhs);
238     jerry_release_value (tests[idx].expected);
239     jerry_release_value (result);
240   }
241 
242   jerry_value_t obj3 = jerry_eval ((const jerry_char_t *) "o={valueOf:function(){throw 5}};o", 33, JERRY_PARSE_NO_OPTS);
243 
244   test_error_entry_t error_tests[] =
245   {
246     /* Testing addition (+) */
247     T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (err1), jerry_acquire_value (err1)),
248     T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (err1), jerry_create_undefined ()),
249     T_ERR (JERRY_BIN_OP_ADD, jerry_create_undefined (), jerry_acquire_value (err1)),
250 
251     /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
252     T_ARI (jerry_acquire_value (err1), jerry_acquire_value (err1)),
253     T_ARI (jerry_acquire_value (err1), jerry_create_undefined ()),
254     T_ARI (jerry_create_undefined (), jerry_acquire_value (err1)),
255 
256     /* Testing addition (+) */
257     T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_undefined ()),
258     T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_null ()),
259     T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_boolean (true)),
260     T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_boolean (false)),
261     T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_acquire_value (obj2)),
262     T_ERR (JERRY_BIN_OP_ADD, jerry_acquire_value (obj3), jerry_create_string ((const jerry_char_t *) "foo")),
263 
264     /* Testing subtraction (-), multiplication (*), division (/), remainder (%) */
265     T_ARI (jerry_acquire_value (obj3), jerry_create_undefined ()),
266     T_ARI (jerry_acquire_value (obj3), jerry_create_null ()),
267     T_ARI (jerry_acquire_value (obj3), jerry_create_boolean (true)),
268     T_ARI (jerry_acquire_value (obj3), jerry_create_boolean (false)),
269     T_ARI (jerry_acquire_value (obj3), jerry_acquire_value (obj2)),
270     T_ARI (jerry_acquire_value (obj3), jerry_create_string ((const jerry_char_t *) "foo")),
271   };
272 
273   for (uint32_t idx = 0; idx < sizeof (error_tests) / sizeof (test_error_entry_t); idx++)
274   {
275     jerry_value_t result = jerry_binary_operation (tests[idx].op, error_tests[idx].lhs, error_tests[idx].rhs);
276     TEST_ASSERT (jerry_value_is_error (result));
277     jerry_release_value (error_tests[idx].lhs);
278     jerry_release_value (error_tests[idx].rhs);
279     jerry_release_value (result);
280   }
281 
282   jerry_release_value (obj1);
283   jerry_release_value (obj2);
284   jerry_release_value (obj3);
285   jerry_release_value (err1);
286 
287   jerry_cleanup ();
288 
289   return 0;
290 } /* main */
291