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 = (a?3:4); r = x", "3", "4", 19 "'use strict'; const x = a; r = x", "123", "0", 20 "'use strict'; const x = (r = x)", throws, throws, 21 "'use strict'; const x = (a?5:6); r = x", "5", "6", 22 "'use strict'; let x = a; r = x", "123", "0", 23 "'use strict'; let x = (r = x)", throws, throws, 24 "'use strict'; let x = (a?7:8); r = x", "7", "8", 25 NULL}; 26 27 static const char* store_tests[] = { 28 "var x = 1; x = a; r = x", "123", "0", 29 "var x = (a?(x=4,2):3); r = x", "2", "3", 30 "var x = (a?4:5); x = a; r = x", "123", "0", 31 // Assignments to 'const' are SyntaxErrors, handled by the parser, 32 // hence we cannot test them here because they are early errors. 33 "'use strict'; let x = 1; x = a; r = x", "123", "0", 34 "'use strict'; let x = (a?(x=4,2):3); r = x", throws, "3", 35 "'use strict'; let x = (a?4:5); x = a; r = x", "123", "0", 36 NULL}; 37 38 39 static void RunVariableTests(const char* source, const char* tests[]) { 40 EmbeddedVector<char, 512> buffer; 41 42 for (int i = 0; tests[i] != NULL; i += 3) { 43 SNPrintF(buffer, source, tests[i]); 44 PrintF("#%d: %s\n", i / 3, buffer.start()); 45 FunctionTester T(buffer.start()); 46 47 // Check function with non-falsey parameter. 48 if (tests[i + 1] != throws) { 49 Handle<Object> r = v8::Utils::OpenHandle(*CompileRun(tests[i + 1])); 50 T.CheckCall(r, T.Val(123), T.Val("result")); 51 } else { 52 T.CheckThrows(T.Val(123), T.Val("result")); 53 } 54 55 // Check function with falsey parameter. 56 if (tests[i + 2] != throws) { 57 Handle<Object> r = v8::Utils::OpenHandle(*CompileRun(tests[i + 2])); 58 T.CheckCall(r, T.Val(0.0), T.Val("result")); 59 } else { 60 T.CheckThrows(T.Val(0.0), T.Val("result")); 61 } 62 } 63 } 64 65 66 TEST(StackLoadVariables) { 67 const char* source = "(function(a,r) { %s; return r; })"; 68 RunVariableTests(source, load_tests); 69 } 70 71 72 TEST(ContextLoadVariables) { 73 const char* source = "(function(a,r) { %s; function f() {x} return r; })"; 74 RunVariableTests(source, load_tests); 75 } 76 77 78 TEST(StackStoreVariables) { 79 const char* source = "(function(a,r) { %s; return r; })"; 80 RunVariableTests(source, store_tests); 81 } 82 83 84 TEST(ContextStoreVariables) { 85 const char* source = "(function(a,r) { %s; function f() {x} return r; })"; 86 RunVariableTests(source, store_tests); 87 } 88 89 90 TEST(SelfReferenceVariable) { 91 FunctionTester T("(function self() { return self; })"); 92 93 T.CheckCall(T.function); 94 CompileRun("var self = 'not a function'"); 95 T.CheckCall(T.function); 96 } 97 98 } // namespace compiler 99 } // namespace internal 100 } // namespace v8 101