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