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/contexts.h"
6 : #include "src/flags.h"
7 : #include "src/objects-inl.h"
8 : #include "src/objects.h"
9 : #include "test/cctest/compiler/function-tester.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 : namespace compiler {
14 :
15 26660 : TEST(SimpleCall) {
16 4 : FunctionTester T("(function(foo,a) { return foo(a); })");
17 4 : Handle<JSFunction> foo = T.NewFunction("(function(a) { return a; })");
18 :
19 8 : T.CheckCall(T.Val(3), foo, T.Val(3));
20 8 : T.CheckCall(T.Val(3.1), foo, T.Val(3.1));
21 4 : T.CheckCall(foo, foo, foo);
22 12 : T.CheckCall(T.Val("Abba"), foo, T.Val("Abba"));
23 4 : }
24 :
25 :
26 26660 : TEST(SimpleCall2) {
27 4 : FunctionTester T("(function(foo,a) { return foo(a); })");
28 4 : FunctionTester U("(function(a) { return a; })");
29 :
30 8 : T.CheckCall(T.Val(3), U.function, T.Val(3));
31 8 : T.CheckCall(T.Val(3.1), U.function, T.Val(3.1));
32 4 : T.CheckCall(U.function, U.function, U.function);
33 12 : T.CheckCall(T.Val("Abba"), U.function, T.Val("Abba"));
34 4 : }
35 :
36 :
37 26660 : TEST(ConstCall) {
38 4 : FunctionTester T("(function(foo,a) { return foo(a,3); })");
39 4 : FunctionTester U("(function (a,b) { return a + b; })");
40 :
41 8 : T.CheckCall(T.Val(6), U.function, T.Val(3));
42 8 : T.CheckCall(T.Val(6.1), U.function, T.Val(3.1));
43 8 : T.CheckCall(T.Val("function (a,b) { return a + b; }3"), U.function,
44 4 : U.function);
45 12 : T.CheckCall(T.Val("Abba3"), U.function, T.Val("Abba"));
46 4 : }
47 :
48 :
49 26660 : TEST(ConstCall2) {
50 4 : FunctionTester T("(function(foo,a) { return foo(a,\"3\"); })");
51 4 : FunctionTester U("(function (a,b) { return a + b; })");
52 :
53 12 : T.CheckCall(T.Val("33"), U.function, T.Val(3));
54 12 : T.CheckCall(T.Val("3.13"), U.function, T.Val(3.1));
55 8 : T.CheckCall(T.Val("function (a,b) { return a + b; }3"), U.function,
56 4 : U.function);
57 12 : T.CheckCall(T.Val("Abba3"), U.function, T.Val("Abba"));
58 4 : }
59 :
60 :
61 26660 : TEST(PropertyNamedCall) {
62 4 : FunctionTester T("(function(a,b) { return a.foo(b,23); })");
63 : CompileRun("function foo(y,z) { return this.x + y + z; }");
64 :
65 8 : T.CheckCall(T.Val(32), T.NewObject("({ foo:foo, x:4 })"), T.Val(5));
66 16 : T.CheckCall(T.Val("xy23"), T.NewObject("({ foo:foo, x:'x' })"), T.Val("y"));
67 8 : T.CheckCall(T.nan(), T.NewObject("({ foo:foo, y:0 })"), T.Val(3));
68 4 : }
69 :
70 :
71 26660 : TEST(PropertyKeyedCall) {
72 4 : FunctionTester T("(function(a,b) { var f = 'foo'; return a[f](b,23); })");
73 : CompileRun("function foo(y,z) { return this.x + y + z; }");
74 :
75 8 : T.CheckCall(T.Val(32), T.NewObject("({ foo:foo, x:4 })"), T.Val(5));
76 16 : T.CheckCall(T.Val("xy23"), T.NewObject("({ foo:foo, x:'x' })"), T.Val("y"));
77 8 : T.CheckCall(T.nan(), T.NewObject("({ foo:foo, y:0 })"), T.Val(3));
78 4 : }
79 :
80 :
81 26660 : TEST(GlobalCall) {
82 4 : FunctionTester T("(function(a,b) { return foo(a,b); })");
83 : CompileRun("function foo(a,b) { return a + b + this.c; }");
84 : CompileRun("var c = 23;");
85 :
86 4 : T.CheckCall(T.Val(32), T.Val(4), T.Val(5));
87 16 : T.CheckCall(T.Val("xy23"), T.Val("x"), T.Val("y"));
88 4 : T.CheckCall(T.nan(), T.undefined(), T.Val(3));
89 4 : }
90 :
91 :
92 26660 : TEST(LookupCall) {
93 4 : FunctionTester T("(function(a,b) { with (a) { return foo(a,b); } })");
94 :
95 : CompileRun("function f1(a,b) { return a.val + b; }");
96 8 : T.CheckCall(T.Val(5), T.NewObject("({ foo:f1, val:2 })"), T.Val(3));
97 16 : T.CheckCall(T.Val("xy"), T.NewObject("({ foo:f1, val:'x' })"), T.Val("y"));
98 :
99 : CompileRun("function f2(a,b) { return this.val + b; }");
100 8 : T.CheckCall(T.Val(9), T.NewObject("({ foo:f2, val:4 })"), T.Val(5));
101 16 : T.CheckCall(T.Val("xy"), T.NewObject("({ foo:f2, val:'x' })"), T.Val("y"));
102 4 : }
103 :
104 :
105 26660 : TEST(MismatchCallTooFew) {
106 4 : FunctionTester T("(function(a,b) { return foo(a,b); })");
107 : CompileRun("function foo(a,b,c) { return a + b + c; }");
108 :
109 4 : T.CheckCall(T.nan(), T.Val(23), T.Val(42));
110 4 : T.CheckCall(T.nan(), T.Val(4.2), T.Val(2.3));
111 16 : T.CheckCall(T.Val("abundefined"), T.Val("a"), T.Val("b"));
112 4 : }
113 :
114 :
115 26660 : TEST(MismatchCallTooMany) {
116 4 : FunctionTester T("(function(a,b) { return foo(a,b); })");
117 : CompileRun("function foo(a) { return a; }");
118 :
119 4 : T.CheckCall(T.Val(23), T.Val(23), T.Val(42));
120 4 : T.CheckCall(T.Val(4.2), T.Val(4.2), T.Val(2.3));
121 16 : T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b"));
122 4 : }
123 :
124 :
125 26660 : TEST(ConstructorCall) {
126 4 : FunctionTester T("(function(a,b) { return new foo(a,b).value; })");
127 : CompileRun("function foo(a,b) { return { value: a + b + this.c }; }");
128 : CompileRun("foo.prototype.c = 23;");
129 :
130 4 : T.CheckCall(T.Val(32), T.Val(4), T.Val(5));
131 16 : T.CheckCall(T.Val("xy23"), T.Val("x"), T.Val("y"));
132 4 : T.CheckCall(T.nan(), T.undefined(), T.Val(3));
133 4 : }
134 :
135 :
136 26660 : TEST(RuntimeCall) {
137 4 : FLAG_allow_natives_syntax = true;
138 4 : FunctionTester T("(function(a) { return %IsJSReceiver(a); })");
139 :
140 4 : T.CheckCall(T.false_value(), T.Val(23), T.undefined());
141 4 : T.CheckCall(T.false_value(), T.Val(4.2), T.undefined());
142 8 : T.CheckCall(T.false_value(), T.Val("str"), T.undefined());
143 4 : T.CheckCall(T.false_value(), T.true_value(), T.undefined());
144 4 : T.CheckCall(T.false_value(), T.false_value(), T.undefined());
145 4 : T.CheckCall(T.false_value(), T.undefined(), T.undefined());
146 8 : T.CheckCall(T.true_value(), T.NewObject("({})"), T.undefined());
147 8 : T.CheckCall(T.true_value(), T.NewObject("([])"), T.undefined());
148 4 : }
149 :
150 :
151 26660 : TEST(RuntimeCallInline) {
152 4 : FLAG_allow_natives_syntax = true;
153 4 : FunctionTester T("(function(a) { return %_IsJSReceiver(a); })");
154 :
155 4 : T.CheckCall(T.false_value(), T.Val(23), T.undefined());
156 4 : T.CheckCall(T.false_value(), T.Val(4.2), T.undefined());
157 8 : T.CheckCall(T.false_value(), T.Val("str"), T.undefined());
158 4 : T.CheckCall(T.false_value(), T.true_value(), T.undefined());
159 4 : T.CheckCall(T.false_value(), T.false_value(), T.undefined());
160 4 : T.CheckCall(T.false_value(), T.undefined(), T.undefined());
161 8 : T.CheckCall(T.true_value(), T.NewObject("({})"), T.undefined());
162 8 : T.CheckCall(T.true_value(), T.NewObject("([])"), T.undefined());
163 4 : }
164 :
165 :
166 26660 : TEST(EvalCall) {
167 4 : FunctionTester T("(function(a,b) { return eval(a); })");
168 8 : Handle<JSObject> g(T.function->context()->global_object()->global_proxy(),
169 4 : T.isolate);
170 :
171 8 : T.CheckCall(T.Val(23), T.Val("17 + 6"), T.undefined());
172 16 : T.CheckCall(T.Val("'Y'; a"), T.Val("'Y'; a"), T.Val("b-val"));
173 16 : T.CheckCall(T.Val("b-val"), T.Val("'Y'; b"), T.Val("b-val"));
174 8 : T.CheckCall(g, T.Val("this"), T.undefined());
175 8 : T.CheckCall(g, T.Val("'use strict'; this"), T.undefined());
176 :
177 : CompileRun("eval = function(x) { return x; }");
178 12 : T.CheckCall(T.Val("17 + 6"), T.Val("17 + 6"), T.undefined());
179 :
180 : CompileRun("eval = function(x) { return this; }");
181 8 : T.CheckCall(g, T.Val("17 + 6"), T.undefined());
182 :
183 : CompileRun("eval = function(x) { 'use strict'; return this; }");
184 8 : T.CheckCall(T.undefined(), T.Val("17 + 6"), T.undefined());
185 4 : }
186 :
187 :
188 26660 : TEST(ReceiverPatching) {
189 : // TODO(turbofan): Note that this test only checks that the function prologue
190 : // patches an undefined receiver to the global receiver. If this starts to
191 : // fail once we fix the calling protocol, just remove this test.
192 4 : FunctionTester T("(function(a) { return this; })");
193 8 : Handle<JSObject> g(T.function->context()->global_object()->global_proxy(),
194 4 : T.isolate);
195 4 : T.CheckCall(g, T.undefined());
196 4 : }
197 :
198 :
199 26660 : TEST(CallEval) {
200 : FunctionTester T(
201 : "var x = 42;"
202 : "(function () {"
203 : "function bar() { return eval('x') };"
204 : "return bar;"
205 4 : "})();");
206 :
207 8 : T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
208 4 : }
209 :
210 : } // namespace compiler
211 : } // namespace internal
212 79968 : } // namespace v8
|