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. 4 5 #include "test/cctest/compiler/function-tester.h" 6 7 namespace v8 { 8 namespace internal { 9 namespace compiler { 10 11 static const char* throws = NULL; 12 13 static const char* load_tests[] = { 14 "var x = a; r = x", "123", "0", 15 "var x = (r = x)", "undefined", "undefined", 16 "var x = (a?1:2); r = x", "1", "2", 17 "const x = a; r = x", "123", "0", 18 "const x = (r = x)", "undefined", "undefined", 19 "const x = (a?3:4); r = x", "3", "4", 20 "'use strict'; const x = a; r = x", "123", "0", 21 "'use strict'; const x = (r = x)", throws, throws, 22 "'use strict'; const x = (a?5:6); r = x", "5", "6", 23 "'use strict'; let x = a; r = x", "123", "0", 24 "'use strict'; let x = (r = x)", throws, throws, 25 "'use strict'; let x = (a?7:8); r = x", "7", "8", 26 NULL}; 27 28 static const char* store_tests[] = { 29 "var x = 1; x = a; r = x", "123", "0", 30 "var x = (a?(x=4,2):3); r = x", "2", "3", 31 "var x = (a?4:5); x = a; r = x", "123", "0", 32 "const x = 1; x = a; r = x", "1", "1", 33 "const x = (a?(x=4,2):3); r = x", "2", "3", 34 "const x = (a?4:5); x = a; r = x", "4", "5", 35 // Assignments to 'const' are SyntaxErrors, handled by the parser, 36 // hence we cannot test them here because they are early errors. 37 "'use strict'; let x = 1; x = a; r = x", "123", "0", 38 "'use strict'; let x = (a?(x=4,2):3); r = x", throws, "3", 39 "'use strict'; let x = (a?4:5); x = a; r = x", "123", "0", 40 NULL}; 41 42 static const char* bind_tests[] = { 43 "if (a) { const x = a }; r = x;", "123", "undefined", 44 "for (; a > 0; a--) { const x = a }; r = x", "123", "undefined", 45 // Re-initialization of variables other than legacy 'const' is not 46 // possible due to sane variable scoping, hence no tests here. 47 NULL}; 48 49 50 static void RunVariableTests(const char* source, const char* tests[]) { 51 i::FLAG_legacy_const = true; 52 EmbeddedVector<char, 512> buffer; 53 54 for (int i = 0; tests[i] != NULL; i += 3) { 55 SNPrintF(buffer, source, tests[i]); 56 PrintF("#%d: %s\n", i / 3, buffer.start()); 57 FunctionTester T(buffer.start()); 58 59 // Check function with non-falsey parameter. 60 if (tests[i + 1] != throws) { 61 Handle<Object> r = v8::Utils::OpenHandle(*CompileRun(tests[i + 1])); 62 T.CheckCall(r, T.Val(123), T.Val("result")); 63 } else { 64 T.CheckThrows(T.Val(123), T.Val("result")); 65 } 66 67 // Check function with falsey parameter. 68 if (tests[i + 2] != throws) { 69 Handle<Object> r = v8::Utils::OpenHandle(*CompileRun(tests[i + 2])); 70 T.CheckCall(r, T.Val(0.0), T.Val("result")); 71 } else { 72 T.CheckThrows(T.Val(0.0), T.Val("result")); 73 } 74 } 75 } 76 77 78 TEST(StackLoadVariables) { 79 const char* source = "(function(a,r) { %s; return r; })"; 80 RunVariableTests(source, load_tests); 81 } 82 83 84 TEST(ContextLoadVariables) { 85 const char* source = "(function(a,r) { %s; function f() {x} return r; })"; 86 RunVariableTests(source, load_tests); 87 } 88 89 90 TEST(StackStoreVariables) { 91 const char* source = "(function(a,r) { %s; return r; })"; 92 RunVariableTests(source, store_tests); 93 } 94 95 96 TEST(ContextStoreVariables) { 97 const char* source = "(function(a,r) { %s; function f() {x} return r; })"; 98 RunVariableTests(source, store_tests); 99 } 100 101 102 TEST(StackInitializeVariables) { 103 const char* source = "(function(a,r) { %s; return r; })"; 104 RunVariableTests(source, bind_tests); 105 } 106 107 108 TEST(ContextInitializeVariables) { 109 const char* source = "(function(a,r) { %s; function f() {x} return r; })"; 110 RunVariableTests(source, bind_tests); 111 } 112 113 114 TEST(SelfReferenceVariable) { 115 FunctionTester T("(function self() { return self; })"); 116 117 T.CheckCall(T.function); 118 CompileRun("var self = 'not a function'"); 119 T.CheckCall(T.function); 120 } 121 122 } // namespace compiler 123 } // namespace internal 124 } // namespace v8 125