blob: 06cfcd2c9ff1763ff535fddbde06574207fca76d [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "test/cctest/compiler/function-tester.h"
6
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007namespace v8 {
8namespace internal {
9namespace compiler {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010
11TEST(SimpleCall) {
12 FunctionTester T("(function(foo,a) { return foo(a); })");
13 Handle<JSFunction> foo = T.NewFunction("(function(a) { return a; })");
14
15 T.CheckCall(T.Val(3), foo, T.Val(3));
16 T.CheckCall(T.Val(3.1), foo, T.Val(3.1));
17 T.CheckCall(foo, foo, foo);
18 T.CheckCall(T.Val("Abba"), foo, T.Val("Abba"));
19}
20
21
22TEST(SimpleCall2) {
23 FunctionTester T("(function(foo,a) { return foo(a); })");
Ben Murdoch097c5b22016-05-18 11:27:45 +010024 FunctionTester U("(function(a) { return a; })");
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025
Ben Murdoch097c5b22016-05-18 11:27:45 +010026 T.CheckCall(T.Val(3), U.function, T.Val(3));
27 T.CheckCall(T.Val(3.1), U.function, T.Val(3.1));
28 T.CheckCall(U.function, U.function, U.function);
29 T.CheckCall(T.Val("Abba"), U.function, T.Val("Abba"));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030}
31
32
33TEST(ConstCall) {
34 FunctionTester T("(function(foo,a) { return foo(a,3); })");
Ben Murdoch097c5b22016-05-18 11:27:45 +010035 FunctionTester U("(function(a,b) { return a + b; })");
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036
Ben Murdoch097c5b22016-05-18 11:27:45 +010037 T.CheckCall(T.Val(6), U.function, T.Val(3));
38 T.CheckCall(T.Val(6.1), U.function, T.Val(3.1));
39 T.CheckCall(T.Val("function (a,b) { return a + b; }3"), U.function,
40 U.function);
41 T.CheckCall(T.Val("Abba3"), U.function, T.Val("Abba"));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042}
43
44
45TEST(ConstCall2) {
46 FunctionTester T("(function(foo,a) { return foo(a,\"3\"); })");
Ben Murdoch097c5b22016-05-18 11:27:45 +010047 FunctionTester U("(function(a,b) { return a + b; })");
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048
Ben Murdoch097c5b22016-05-18 11:27:45 +010049 T.CheckCall(T.Val("33"), U.function, T.Val(3));
50 T.CheckCall(T.Val("3.13"), U.function, T.Val(3.1));
51 T.CheckCall(T.Val("function (a,b) { return a + b; }3"), U.function,
52 U.function);
53 T.CheckCall(T.Val("Abba3"), U.function, T.Val("Abba"));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054}
55
56
57TEST(PropertyNamedCall) {
58 FunctionTester T("(function(a,b) { return a.foo(b,23); })");
59 CompileRun("function foo(y,z) { return this.x + y + z; }");
60
61 T.CheckCall(T.Val(32), T.NewObject("({ foo:foo, x:4 })"), T.Val(5));
62 T.CheckCall(T.Val("xy23"), T.NewObject("({ foo:foo, x:'x' })"), T.Val("y"));
63 T.CheckCall(T.nan(), T.NewObject("({ foo:foo, y:0 })"), T.Val(3));
64}
65
66
67TEST(PropertyKeyedCall) {
68 FunctionTester T("(function(a,b) { var f = 'foo'; return a[f](b,23); })");
69 CompileRun("function foo(y,z) { return this.x + y + z; }");
70
71 T.CheckCall(T.Val(32), T.NewObject("({ foo:foo, x:4 })"), T.Val(5));
72 T.CheckCall(T.Val("xy23"), T.NewObject("({ foo:foo, x:'x' })"), T.Val("y"));
73 T.CheckCall(T.nan(), T.NewObject("({ foo:foo, y:0 })"), T.Val(3));
74}
75
76
77TEST(GlobalCall) {
78 FunctionTester T("(function(a,b) { return foo(a,b); })");
79 CompileRun("function foo(a,b) { return a + b + this.c; }");
80 CompileRun("var c = 23;");
81
82 T.CheckCall(T.Val(32), T.Val(4), T.Val(5));
83 T.CheckCall(T.Val("xy23"), T.Val("x"), T.Val("y"));
84 T.CheckCall(T.nan(), T.undefined(), T.Val(3));
85}
86
87
88TEST(LookupCall) {
89 FunctionTester T("(function(a,b) { with (a) { return foo(a,b); } })");
90
91 CompileRun("function f1(a,b) { return a.val + b; }");
92 T.CheckCall(T.Val(5), T.NewObject("({ foo:f1, val:2 })"), T.Val(3));
93 T.CheckCall(T.Val("xy"), T.NewObject("({ foo:f1, val:'x' })"), T.Val("y"));
94
95 CompileRun("function f2(a,b) { return this.val + b; }");
96 T.CheckCall(T.Val(9), T.NewObject("({ foo:f2, val:4 })"), T.Val(5));
97 T.CheckCall(T.Val("xy"), T.NewObject("({ foo:f2, val:'x' })"), T.Val("y"));
98}
99
100
101TEST(MismatchCallTooFew) {
102 FunctionTester T("(function(a,b) { return foo(a,b); })");
103 CompileRun("function foo(a,b,c) { return a + b + c; }");
104
105 T.CheckCall(T.nan(), T.Val(23), T.Val(42));
106 T.CheckCall(T.nan(), T.Val(4.2), T.Val(2.3));
107 T.CheckCall(T.Val("abundefined"), T.Val("a"), T.Val("b"));
108}
109
110
111TEST(MismatchCallTooMany) {
112 FunctionTester T("(function(a,b) { return foo(a,b); })");
113 CompileRun("function foo(a) { return a; }");
114
115 T.CheckCall(T.Val(23), T.Val(23), T.Val(42));
116 T.CheckCall(T.Val(4.2), T.Val(4.2), T.Val(2.3));
117 T.CheckCall(T.Val("a"), T.Val("a"), T.Val("b"));
118}
119
120
121TEST(ConstructorCall) {
122 FunctionTester T("(function(a,b) { return new foo(a,b).value; })");
123 CompileRun("function foo(a,b) { return { value: a + b + this.c }; }");
124 CompileRun("foo.prototype.c = 23;");
125
126 T.CheckCall(T.Val(32), T.Val(4), T.Val(5));
127 T.CheckCall(T.Val("xy23"), T.Val("x"), T.Val("y"));
128 T.CheckCall(T.nan(), T.undefined(), T.Val(3));
129}
130
131
Ben Murdochda12d292016-06-02 14:46:10 +0100132TEST(RuntimeCall) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000133 FLAG_allow_natives_syntax = true;
Ben Murdochda12d292016-06-02 14:46:10 +0100134 FunctionTester T("(function(a) { return %IsJSReceiver(a); })");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135
Ben Murdochda12d292016-06-02 14:46:10 +0100136 T.CheckCall(T.false_value(), T.Val(23), T.undefined());
137 T.CheckCall(T.false_value(), T.Val(4.2), T.undefined());
138 T.CheckCall(T.false_value(), T.Val("str"), T.undefined());
139 T.CheckCall(T.false_value(), T.true_value(), T.undefined());
140 T.CheckCall(T.false_value(), T.false_value(), T.undefined());
141 T.CheckCall(T.false_value(), T.undefined(), T.undefined());
142 T.CheckCall(T.true_value(), T.NewObject("({})"), T.undefined());
143 T.CheckCall(T.true_value(), T.NewObject("([])"), T.undefined());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000144}
145
146
147TEST(RuntimeCallInline) {
148 FLAG_allow_natives_syntax = true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149 FunctionTester T("(function(a) { return %_IsJSReceiver(a); })");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150
151 T.CheckCall(T.false_value(), T.Val(23), T.undefined());
152 T.CheckCall(T.false_value(), T.Val(4.2), T.undefined());
153 T.CheckCall(T.false_value(), T.Val("str"), T.undefined());
154 T.CheckCall(T.false_value(), T.true_value(), T.undefined());
155 T.CheckCall(T.false_value(), T.false_value(), T.undefined());
156 T.CheckCall(T.false_value(), T.undefined(), T.undefined());
157 T.CheckCall(T.true_value(), T.NewObject("({})"), T.undefined());
158 T.CheckCall(T.true_value(), T.NewObject("([])"), T.undefined());
159}
160
161
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000162TEST(EvalCall) {
163 FunctionTester T("(function(a,b) { return eval(a); })");
164 Handle<JSObject> g(T.function->context()->global_object()->global_proxy());
165
166 T.CheckCall(T.Val(23), T.Val("17 + 6"), T.undefined());
167 T.CheckCall(T.Val("'Y'; a"), T.Val("'Y'; a"), T.Val("b-val"));
168 T.CheckCall(T.Val("b-val"), T.Val("'Y'; b"), T.Val("b-val"));
169 T.CheckCall(g, T.Val("this"), T.undefined());
170 T.CheckCall(g, T.Val("'use strict'; this"), T.undefined());
171
172 CompileRun("eval = function(x) { return x; }");
173 T.CheckCall(T.Val("17 + 6"), T.Val("17 + 6"), T.undefined());
174
175 CompileRun("eval = function(x) { return this; }");
176 T.CheckCall(g, T.Val("17 + 6"), T.undefined());
177
178 CompileRun("eval = function(x) { 'use strict'; return this; }");
179 T.CheckCall(T.undefined(), T.Val("17 + 6"), T.undefined());
180}
181
182
183TEST(ReceiverPatching) {
184 // TODO(turbofan): Note that this test only checks that the function prologue
185 // patches an undefined receiver to the global receiver. If this starts to
186 // fail once we fix the calling protocol, just remove this test.
187 FunctionTester T("(function(a) { return this; })");
188 Handle<JSObject> g(T.function->context()->global_object()->global_proxy());
189 T.CheckCall(g, T.undefined());
190}
191
192
193TEST(CallEval) {
194 FunctionTester T(
195 "var x = 42;"
196 "(function () {"
197 "function bar() { return eval('x') };"
198 "return bar;"
199 "})();");
200
201 T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
202}
203
204
205TEST(ContextLoadedFromActivation) {
206 const char* script =
207 "var x = 42;"
208 "(function() {"
209 " return function () { return x };"
210 "})()";
211
212 // Disable context specialization.
213 FunctionTester T(script);
214 v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
215 v8::Context::Scope scope(context);
216 v8::Local<v8::Value> value = CompileRun(script);
217 i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
218 i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
219 jsfun->set_code(T.function->code());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000220 jsfun->set_shared(T.function->shared());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100221 jsfun->set_literals(T.function->literals());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000222 CHECK(context->Global()
223 ->Set(context, v8_str("foo"), v8::Utils::CallableToLocal(jsfun))
224 .FromJust());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225 CompileRun("var x = 24;");
226 ExpectInt32("foo();", 24);
227}
228
229
230TEST(BuiltinLoadedFromActivation) {
231 const char* script =
232 "var x = 42;"
233 "(function() {"
234 " return function () { return this; };"
235 "})()";
236
237 // Disable context specialization.
238 FunctionTester T(script);
239 v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
240 v8::Context::Scope scope(context);
241 v8::Local<v8::Value> value = CompileRun(script);
242 i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
243 i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
244 jsfun->set_code(T.function->code());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245 jsfun->set_shared(T.function->shared());
Ben Murdoch61f157c2016-09-16 13:49:30 +0100246 jsfun->set_literals(T.function->literals());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000247 CHECK(context->Global()
248 ->Set(context, v8_str("foo"), v8::Utils::CallableToLocal(jsfun))
249 .FromJust());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250 CompileRun("var x = 24;");
251 ExpectObject("foo()", context->Global());
252}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000253
254} // namespace compiler
255} // namespace internal
256} // namespace v8