1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "test/cctest/compiler/function-tester.h"
9 using namespace v8::internal;
10 using namespace v8::internal::compiler;
13 FunctionTester T("(function(a,b) { return a + b; })");
16 T.CheckCall(-11, -2, -9);
17 T.CheckCall(-11, -1.5, -9.5);
18 T.CheckCall(T.Val("AB"), T.Val("A"), T.Val("B"));
19 T.CheckCall(T.Val("A11"), T.Val("A"), T.Val(11));
20 T.CheckCall(T.Val("12B"), T.Val(12), T.Val("B"));
21 T.CheckCall(T.Val("38"), T.Val("3"), T.Val("8"));
22 T.CheckCall(T.Val("31"), T.Val("3"), T.NewObject("([1])"));
23 T.CheckCall(T.Val("3[object Object]"), T.Val("3"), T.NewObject("({})"));
28 FunctionTester T("(function(a,b) { return a - b; })");
31 T.CheckCall(3.0, 4.5, 1.5);
32 T.CheckCall(T.Val(-9), T.Val("0"), T.Val(9));
33 T.CheckCall(T.Val(-9), T.Val(0.0), T.Val("9"));
34 T.CheckCall(T.Val(1), T.Val("3"), T.Val("2"));
35 T.CheckCall(T.nan(), T.Val("3"), T.Val("B"));
36 T.CheckCall(T.Val(2), T.Val("3"), T.NewObject("([1])"));
37 T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})"));
42 FunctionTester T("(function(a,b) { return a * b; })");
45 T.CheckCall(4.5, 2.0, 2.25);
46 T.CheckCall(T.Val(6), T.Val("3"), T.Val(2));
47 T.CheckCall(T.Val(4.5), T.Val(2.0), T.Val("2.25"));
48 T.CheckCall(T.Val(6), T.Val("3"), T.Val("2"));
49 T.CheckCall(T.nan(), T.Val("3"), T.Val("B"));
50 T.CheckCall(T.Val(3), T.Val("3"), T.NewObject("([1])"));
51 T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})"));
56 FunctionTester T("(function(a,b) { return a / b; })");
59 T.CheckCall(2.1, 8.4, 4);
60 T.CheckCall(V8_INFINITY, 8, 0);
61 T.CheckCall(-V8_INFINITY, -8, 0);
62 T.CheckCall(T.infinity(), T.Val(8), T.Val("0"));
63 T.CheckCall(T.minus_infinity(), T.Val("-8"), T.Val(0.0));
64 T.CheckCall(T.Val(1.5), T.Val("3"), T.Val("2"));
65 T.CheckCall(T.nan(), T.Val("3"), T.Val("B"));
66 T.CheckCall(T.Val(1.5), T.Val("3"), T.NewObject("([2])"));
67 T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})"));
72 FunctionTester T("(function(a,b) { return a % b; })");
75 T.CheckCall(T.Val(3), T.Val("8"), T.Val(5));
76 T.CheckCall(T.Val(3), T.Val(8), T.Val("5"));
77 T.CheckCall(T.Val(1), T.Val("3"), T.Val("2"));
78 T.CheckCall(T.nan(), T.Val("3"), T.Val("B"));
79 T.CheckCall(T.Val(1), T.Val("3"), T.NewObject("([2])"));
80 T.CheckCall(T.nan(), T.Val("3"), T.NewObject("({})"));
84 TEST(BinopShiftLeft) {
85 FunctionTester T("(function(a,b) { return a << b; })");
88 T.CheckCall(T.Val(4), T.Val("2"), T.Val(1));
89 T.CheckCall(T.Val(4), T.Val(2), T.Val("1"));
93 TEST(BinopShiftRight) {
94 FunctionTester T("(function(a,b) { return a >> b; })");
97 T.CheckCall(-4, -8, 1);
98 T.CheckCall(T.Val(4), T.Val("8"), T.Val(1));
99 T.CheckCall(T.Val(4), T.Val(8), T.Val("1"));
103 TEST(BinopShiftRightLogical) {
104 FunctionTester T("(function(a,b) { return a >>> b; })");
106 T.CheckCall(4, 8, 1);
107 T.CheckCall(0x7ffffffc, -8, 1);
108 T.CheckCall(T.Val(4), T.Val("8"), T.Val(1));
109 T.CheckCall(T.Val(4), T.Val(8), T.Val("1"));
114 FunctionTester T("(function(a,b) { return a & b; })");
116 T.CheckCall(7, 7, 15);
117 T.CheckCall(7, 15, 7);
118 T.CheckCall(T.Val(7), T.Val("15"), T.Val(7));
119 T.CheckCall(T.Val(7), T.Val(15), T.Val("7"));
124 FunctionTester T("(function(a,b) { return a | b; })");
126 T.CheckCall(6, 4, 2);
127 T.CheckCall(6, 2, 4);
128 T.CheckCall(T.Val(6), T.Val("2"), T.Val(4));
129 T.CheckCall(T.Val(6), T.Val(2), T.Val("4"));
134 FunctionTester T("(function(a,b) { return a ^ b; })");
136 T.CheckCall(7, 15, 8);
137 T.CheckCall(7, 8, 15);
138 T.CheckCall(T.Val(7), T.Val("8"), T.Val(15));
139 T.CheckCall(T.Val(7), T.Val(8), T.Val("15"));
143 TEST(BinopStrictEqual) {
144 FunctionTester T("(function(a,b) { return a === b; })");
148 T.CheckTrue(7.1, 7.1);
149 T.CheckFalse(7.1, 8.1);
151 T.CheckTrue(T.Val("7.1"), T.Val("7.1"));
152 T.CheckFalse(T.Val(7.1), T.Val("7.1"));
153 T.CheckFalse(T.Val(7), T.undefined());
154 T.CheckFalse(T.undefined(), T.Val(7));
156 CompileRun("var o = { desc : 'I am a singleton' }");
157 T.CheckFalse(T.NewObject("([1])"), T.NewObject("([1])"));
158 T.CheckFalse(T.NewObject("({})"), T.NewObject("({})"));
159 T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)"));
164 FunctionTester T("(function(a,b) { return a == b; })");
168 T.CheckTrue(7.1, 7.1);
169 T.CheckFalse(7.1, 8.1);
171 T.CheckTrue(T.Val("7.1"), T.Val("7.1"));
172 T.CheckTrue(T.Val(7.1), T.Val("7.1"));
174 CompileRun("var o = { desc : 'I am a singleton' }");
175 T.CheckFalse(T.NewObject("([1])"), T.NewObject("([1])"));
176 T.CheckFalse(T.NewObject("({})"), T.NewObject("({})"));
177 T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)"));
181 TEST(BinopNotEqual) {
182 FunctionTester T("(function(a,b) { return a != b; })");
186 T.CheckFalse(7.1, 7.1);
187 T.CheckTrue(7.1, 8.1);
189 T.CheckFalse(T.Val("7.1"), T.Val("7.1"));
190 T.CheckFalse(T.Val(7.1), T.Val("7.1"));
192 CompileRun("var o = { desc : 'I am a singleton' }");
193 T.CheckTrue(T.NewObject("([1])"), T.NewObject("([1])"));
194 T.CheckTrue(T.NewObject("({})"), T.NewObject("({})"));
195 T.CheckFalse(T.NewObject("(o)"), T.NewObject("(o)"));
199 TEST(BinopLessThan) {
200 FunctionTester T("(function(a,b) { return a < b; })");
204 T.CheckTrue(-8.1, -8);
205 T.CheckFalse(-8, -8.1);
206 T.CheckFalse(0.111, 0.111);
208 T.CheckFalse(T.Val("7.1"), T.Val("7.1"));
209 T.CheckFalse(T.Val(7.1), T.Val("6.1"));
210 T.CheckFalse(T.Val(7.1), T.Val("7.1"));
211 T.CheckTrue(T.Val(7.1), T.Val("8.1"));
215 TEST(BinopLessThanOrEqual) {
216 FunctionTester T("(function(a,b) { return a <= b; })");
220 T.CheckTrue(-8.1, -8);
221 T.CheckFalse(-8, -8.1);
222 T.CheckTrue(0.111, 0.111);
224 T.CheckTrue(T.Val("7.1"), T.Val("7.1"));
225 T.CheckFalse(T.Val(7.1), T.Val("6.1"));
226 T.CheckTrue(T.Val(7.1), T.Val("7.1"));
227 T.CheckTrue(T.Val(7.1), T.Val("8.1"));
231 TEST(BinopGreaterThan) {
232 FunctionTester T("(function(a,b) { return a > b; })");
236 T.CheckFalse(-8.1, -8);
237 T.CheckTrue(-8, -8.1);
238 T.CheckFalse(0.111, 0.111);
240 T.CheckFalse(T.Val("7.1"), T.Val("7.1"));
241 T.CheckTrue(T.Val(7.1), T.Val("6.1"));
242 T.CheckFalse(T.Val(7.1), T.Val("7.1"));
243 T.CheckFalse(T.Val(7.1), T.Val("8.1"));
247 TEST(BinopGreaterThanOrEqual) {
248 FunctionTester T("(function(a,b) { return a >= b; })");
252 T.CheckFalse(-8.1, -8);
253 T.CheckTrue(-8, -8.1);
254 T.CheckTrue(0.111, 0.111);
256 T.CheckTrue(T.Val("7.1"), T.Val("7.1"));
257 T.CheckTrue(T.Val(7.1), T.Val("6.1"));
258 T.CheckTrue(T.Val(7.1), T.Val("7.1"));
259 T.CheckFalse(T.Val(7.1), T.Val("8.1"));
264 FunctionTester T("(function(a,b) { return a in b; })");
266 T.CheckTrue(T.Val("x"), T.NewObject("({x:23})"));
267 T.CheckFalse(T.Val("y"), T.NewObject("({x:42})"));
268 T.CheckFalse(T.Val(123), T.NewObject("({x:65})"));
269 T.CheckTrue(T.Val(1), T.NewObject("([1,2,3])"));
273 TEST(BinopInstanceOf) {
274 FunctionTester T("(function(a,b) { return a instanceof b; })");
276 T.CheckTrue(T.NewObject("(new Number(23))"), T.NewObject("Number"));
277 T.CheckFalse(T.NewObject("(new Number(23))"), T.NewObject("String"));
278 T.CheckFalse(T.NewObject("(new String('a'))"), T.NewObject("Number"));
279 T.CheckTrue(T.NewObject("(new String('b'))"), T.NewObject("String"));
280 T.CheckFalse(T.Val(1), T.NewObject("Number"));
281 T.CheckFalse(T.Val("abc"), T.NewObject("String"));
283 CompileRun("var bound = (function() {}).bind(undefined)");
284 T.CheckTrue(T.NewObject("(new bound())"), T.NewObject("bound"));
285 T.CheckTrue(T.NewObject("(new bound())"), T.NewObject("Object"));
286 T.CheckFalse(T.NewObject("(new bound())"), T.NewObject("Number"));
291 FunctionTester T("(function(a) { return !a; })");
293 T.CheckCall(T.true_value(), T.false_value(), T.undefined());
294 T.CheckCall(T.false_value(), T.true_value(), T.undefined());
295 T.CheckCall(T.true_value(), T.Val(0.0), T.undefined());
296 T.CheckCall(T.false_value(), T.Val(123), T.undefined());
297 T.CheckCall(T.false_value(), T.Val("x"), T.undefined());
298 T.CheckCall(T.true_value(), T.undefined(), T.undefined());
299 T.CheckCall(T.true_value(), T.nan(), T.undefined());
303 TEST(UnopCountPost) {
304 FunctionTester T("(function(a) { return a++; })");
306 T.CheckCall(T.Val(0.0), T.Val(0.0), T.undefined());
307 T.CheckCall(T.Val(2.3), T.Val(2.3), T.undefined());
308 T.CheckCall(T.Val(123), T.Val(123), T.undefined());
309 T.CheckCall(T.Val(7), T.Val("7"), T.undefined());
310 T.CheckCall(T.nan(), T.Val("x"), T.undefined());
311 T.CheckCall(T.nan(), T.undefined(), T.undefined());
312 T.CheckCall(T.Val(1.0), T.true_value(), T.undefined());
313 T.CheckCall(T.Val(0.0), T.false_value(), T.undefined());
314 T.CheckCall(T.nan(), T.nan(), T.undefined());
319 FunctionTester T("(function(a) { return ++a; })");
321 T.CheckCall(T.Val(1.0), T.Val(0.0), T.undefined());
322 T.CheckCall(T.Val(3.3), T.Val(2.3), T.undefined());
323 T.CheckCall(T.Val(124), T.Val(123), T.undefined());
324 T.CheckCall(T.Val(8), T.Val("7"), T.undefined());
325 T.CheckCall(T.nan(), T.Val("x"), T.undefined());
326 T.CheckCall(T.nan(), T.undefined(), T.undefined());
327 T.CheckCall(T.Val(2.0), T.true_value(), T.undefined());
328 T.CheckCall(T.Val(1.0), T.false_value(), T.undefined());
329 T.CheckCall(T.nan(), T.nan(), T.undefined());
333 TEST(PropertyNamedLoad) {
334 FunctionTester T("(function(a,b) { return a.x; })");
336 T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.undefined());
337 T.CheckCall(T.undefined(), T.NewObject("({y:23})"), T.undefined());
341 TEST(PropertyKeyedLoad) {
342 FunctionTester T("(function(a,b) { return a[b]; })");
344 T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.Val("x"));
345 T.CheckCall(T.Val(42), T.NewObject("([23,42,65])"), T.Val(1));
346 T.CheckCall(T.undefined(), T.NewObject("({x:23})"), T.Val("y"));
347 T.CheckCall(T.undefined(), T.NewObject("([23,42,65])"), T.Val(4));
351 TEST(PropertyNamedStore) {
352 FunctionTester T("(function(a) { a.x = 7; return a.x; })");
354 T.CheckCall(T.Val(7), T.NewObject("({})"), T.undefined());
355 T.CheckCall(T.Val(7), T.NewObject("({x:23})"), T.undefined());
359 TEST(PropertyKeyedStore) {
360 FunctionTester T("(function(a,b) { a[b] = 7; return a.x; })");
362 T.CheckCall(T.Val(7), T.NewObject("({})"), T.Val("x"));
363 T.CheckCall(T.Val(7), T.NewObject("({x:23})"), T.Val("x"));
364 T.CheckCall(T.Val(9), T.NewObject("({x:9})"), T.Val("y"));
368 TEST(PropertyNamedDelete) {
369 FunctionTester T("(function(a) { return delete a.x; })");
371 CompileRun("var o = Object.create({}, { x: { value:23 } });");
372 T.CheckTrue(T.NewObject("({x:42})"), T.undefined());
373 T.CheckTrue(T.NewObject("({})"), T.undefined());
374 T.CheckFalse(T.NewObject("(o)"), T.undefined());
378 TEST(PropertyKeyedDelete) {
379 FunctionTester T("(function(a, b) { return delete a[b]; })");
381 CompileRun("function getX() { return 'x'; }");
382 CompileRun("var o = Object.create({}, { x: { value:23 } });");
383 T.CheckTrue(T.NewObject("({x:42})"), T.Val("x"));
384 T.CheckFalse(T.NewObject("(o)"), T.Val("x"));
385 T.CheckFalse(T.NewObject("(o)"), T.NewObject("({toString:getX})"));
390 FunctionTester T("(function() { return g; })");
392 T.CheckThrows(T.undefined(), T.undefined());
393 CompileRun("var g = 23;");
394 T.CheckCall(T.Val(23));
398 TEST(GlobalStoreSloppy) {
399 FunctionTester T("(function(a,b) { g = a + b; return g; })");
401 T.CheckCall(T.Val(33), T.Val(22), T.Val(11));
402 CompileRun("delete g");
403 CompileRun("const g = 23");
404 T.CheckCall(T.Val(23), T.Val(55), T.Val(44));
408 TEST(GlobalStoreStrict) {
409 FunctionTester T("(function(a,b) { 'use strict'; g = a + b; return g; })");
411 T.CheckThrows(T.Val(22), T.Val(11));
412 CompileRun("var g = 'a global variable';");
413 T.CheckCall(T.Val(33), T.Val(22), T.Val(11));
418 FunctionTester T("(function(a,b) { (function(){a}); return a + b; })");
420 T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
421 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
426 FunctionTester T("(function(a,b) { (function(){x}); var x = a; return x; })");
428 T.CheckCall(T.Val(23), T.Val(23), T.undefined());
429 T.CheckCall(T.Val("a"), T.Val("a"), T.undefined());
434 FunctionTester T("(function(a,b) { with(a) { return x + b; } })");
436 T.CheckCall(T.Val(24), T.NewObject("({x:23})"), T.Val(1));
437 T.CheckCall(T.Val(32), T.NewObject("({x:23, b:9})"), T.Val(2));
438 T.CheckCall(T.Val(45), T.NewObject("({__proto__:{x:42}})"), T.Val(3));
439 T.CheckCall(T.Val(69), T.NewObject("({get x() { return 65; }})"), T.Val(4));
444 FunctionTester T("(function(a,b) { var x; with(a) { x = b; } return x; })");
446 T.CheckCall(T.undefined(), T.NewObject("({x:23})"), T.Val(1));
447 T.CheckCall(T.Val(2), T.NewObject("({y:23})"), T.Val(2));
448 T.CheckCall(T.Val(23), T.NewObject("({b:23})"), T.Val(3));
449 T.CheckCall(T.undefined(), T.NewObject("({__proto__:{x:42}})"), T.Val(4));
453 TEST(BlockLoadStore) {
454 FunctionTester T("(function(a) { 'use strict'; { let x = a+a; return x; }})");
456 T.CheckCall(T.Val(46), T.Val(23));
457 T.CheckCall(T.Val("aa"), T.Val("a"));
461 TEST(BlockLoadStoreNested) {
465 "{ let x = a, y = a;"
470 FunctionTester T(src);
472 T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
473 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
477 TEST(ObjectLiteralComputed) {
478 FunctionTester T("(function(a,b) { o = { x:a+b }; return o.x; })");
480 T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
481 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
485 TEST(ObjectLiteralNonString) {
486 FunctionTester T("(function(a,b) { o = { 7:a+b }; return o[7]; })");
488 T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
489 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
493 TEST(ObjectLiteralPrototype) {
494 FunctionTester T("(function(a) { o = { __proto__:a }; return o.x; })");
496 T.CheckCall(T.Val(23), T.NewObject("({x:23})"), T.undefined());
497 T.CheckCall(T.undefined(), T.NewObject("({y:42})"), T.undefined());
501 TEST(ObjectLiteralGetter) {
502 FunctionTester T("(function(a) { o = { get x() {return a} }; return o.x; })");
504 T.CheckCall(T.Val(23), T.Val(23), T.undefined());
505 T.CheckCall(T.Val("x"), T.Val("x"), T.undefined());
510 FunctionTester T("(function(a,b) { o = [1, a + b, 3]; return o[1]; })");
512 T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
513 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));
517 TEST(RegExpLiteral) {
518 FunctionTester T("(function(a) { o = /b/; return o.test(a); })");
520 T.CheckTrue(T.Val("abc"));
521 T.CheckFalse(T.Val("xyz"));
526 FLAG_harmony_classes = true;
527 FLAG_harmony_sloppy = true;
528 FLAG_harmony_object_literals = true;
533 " static y() { return b; }"
534 " get z() { return 0; }"
537 " return new C().x() + C.y();"
539 FunctionTester T(src);
541 T.CheckCall(T.Val(65), T.Val(23), T.Val(42));
542 T.CheckCall(T.Val("ab"), T.Val("a"), T.Val("b"));