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