blob: 5ebc679c1285a944235e7cde1af51214b39a5466 [file] [log] [blame]
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00001// Copyright 2011 the V8 project authors. All rights reserved.
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
ulan@chromium.org57ff8812013-05-10 08:16:55 +000028
29// TODO(dcarney): remove
30#define V8_ALLOW_ACCESS_TO_PERSISTENT_ARROW
31#define V8_ALLOW_ACCESS_TO_RAW_HANDLE_CONSTRUCTOR
32#define V8_ALLOW_ACCESS_TO_PERSISTENT_IMPLICIT
33
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000034#include "v8.h"
35
36#include "api.h"
jkummerow@chromium.org78502a92012-09-06 13:50:42 +000037#include "debug.h"
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000038#include "runtime.h"
39#include "cctest.h"
40
41
kasperl@chromium.org71affb52009-05-26 05:44:31 +000042using ::v8::internal::CStrVector;
43using ::v8::internal::Factory;
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000044using ::v8::internal::Handle;
kasperl@chromium.org71affb52009-05-26 05:44:31 +000045using ::v8::internal::Heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000046using ::v8::internal::Isolate;
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000047using ::v8::internal::JSFunction;
48using ::v8::internal::Object;
kasperl@chromium.org71affb52009-05-26 05:44:31 +000049using ::v8::internal::Runtime;
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000050using ::v8::internal::Script;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +000051using ::v8::internal::SmartArrayPointer;
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000052using ::v8::internal::SharedFunctionInfo;
53using ::v8::internal::String;
54
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000055
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000056static void CheckFunctionName(v8::Handle<v8::Script> script,
57 const char* func_pos_src,
58 const char* ref_inferred_name) {
59 // Get script source.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +000060 Handle<Object> obj = v8::Utils::OpenHandle(*script);
61 Handle<SharedFunctionInfo> shared_function;
62 if (obj->IsSharedFunctionInfo()) {
63 shared_function =
64 Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(*obj));
65 } else {
66 shared_function =
67 Handle<SharedFunctionInfo>(JSFunction::cast(*obj)->shared());
68 }
69 Handle<Script> i_script(Script::cast(shared_function->script()));
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000070 CHECK(i_script->source()->IsString());
71 Handle<String> script_src(String::cast(i_script->source()));
72
73 // Find the position of a given func source substring in the source.
74 Handle<String> func_pos_str =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000075 FACTORY->NewStringFromAscii(CStrVector(func_pos_src));
76 int func_pos = Runtime::StringMatch(Isolate::Current(),
77 script_src,
78 func_pos_str,
79 0);
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000080 CHECK_NE(0, func_pos);
81
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +000082#ifdef ENABLE_DEBUGGER_SUPPORT
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000083 // Obtain SharedFunctionInfo for the function.
jkummerow@chromium.org78502a92012-09-06 13:50:42 +000084 Isolate::Current()->debug()->PrepareForBreakPoints();
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000085 Object* shared_func_info_ptr =
jkummerow@chromium.org78502a92012-09-06 13:50:42 +000086 Isolate::Current()->debug()->FindSharedFunctionInfoInScript(i_script,
87 func_pos);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000088 CHECK(shared_func_info_ptr != HEAP->undefined_value());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000089 Handle<SharedFunctionInfo> shared_func_info(
90 SharedFunctionInfo::cast(shared_func_info_ptr));
91
92 // Verify inferred function name.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +000093 SmartArrayPointer<char> inferred_name =
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000094 shared_func_info->inferred_name()->ToCString();
95 CHECK_EQ(ref_inferred_name, *inferred_name);
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +000096#endif // ENABLE_DEBUGGER_SUPPORT
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +000097}
98
99
100static v8::Handle<v8::Script> Compile(const char* src) {
101 return v8::Script::Compile(v8::String::New(src));
102}
103
104
105TEST(GlobalProperty) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000106 CcTest::InitializeVM();
107 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000108
109 v8::Handle<v8::Script> script = Compile(
110 "fun1 = function() { return 1; }\n"
111 "fun2 = function() { return 2; }\n");
112 CheckFunctionName(script, "return 1", "fun1");
113 CheckFunctionName(script, "return 2", "fun2");
114}
115
116
117TEST(GlobalVar) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000118 CcTest::InitializeVM();
119 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000120
121 v8::Handle<v8::Script> script = Compile(
122 "var fun1 = function() { return 1; }\n"
123 "var fun2 = function() { return 2; }\n");
124 CheckFunctionName(script, "return 1", "fun1");
125 CheckFunctionName(script, "return 2", "fun2");
126}
127
128
129TEST(LocalVar) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000130 CcTest::InitializeVM();
131 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000132
133 v8::Handle<v8::Script> script = Compile(
134 "function outer() {\n"
135 " var fun1 = function() { return 1; }\n"
136 " var fun2 = function() { return 2; }\n"
137 "}");
138 CheckFunctionName(script, "return 1", "fun1");
139 CheckFunctionName(script, "return 2", "fun2");
140}
141
142
143TEST(InConstructor) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000144 CcTest::InitializeVM();
145 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000146
147 v8::Handle<v8::Script> script = Compile(
148 "function MyClass() {\n"
149 " this.method1 = function() { return 1; }\n"
150 " this.method2 = function() { return 2; }\n"
151 "}");
152 CheckFunctionName(script, "return 1", "MyClass.method1");
153 CheckFunctionName(script, "return 2", "MyClass.method2");
154}
155
156
157TEST(Factory) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000158 CcTest::InitializeVM();
159 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000160
161 v8::Handle<v8::Script> script = Compile(
162 "function createMyObj() {\n"
163 " var obj = {};\n"
164 " obj.method1 = function() { return 1; }\n"
165 " obj.method2 = function() { return 2; }\n"
166 " return obj;\n"
167 "}");
168 CheckFunctionName(script, "return 1", "obj.method1");
169 CheckFunctionName(script, "return 2", "obj.method2");
170}
171
172
173TEST(Static) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000174 CcTest::InitializeVM();
175 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000176
177 v8::Handle<v8::Script> script = Compile(
178 "function MyClass() {}\n"
179 "MyClass.static1 = function() { return 1; }\n"
180 "MyClass.static2 = function() { return 2; }\n"
181 "MyClass.MyInnerClass = {}\n"
182 "MyClass.MyInnerClass.static3 = function() { return 3; }\n"
183 "MyClass.MyInnerClass.static4 = function() { return 4; }");
184 CheckFunctionName(script, "return 1", "MyClass.static1");
185 CheckFunctionName(script, "return 2", "MyClass.static2");
186 CheckFunctionName(script, "return 3", "MyClass.MyInnerClass.static3");
187 CheckFunctionName(script, "return 4", "MyClass.MyInnerClass.static4");
188}
189
190
191TEST(Prototype) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000192 CcTest::InitializeVM();
193 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000194
195 v8::Handle<v8::Script> script = Compile(
196 "function MyClass() {}\n"
197 "MyClass.prototype.method1 = function() { return 1; }\n"
198 "MyClass.prototype.method2 = function() { return 2; }\n"
199 "MyClass.MyInnerClass = function() {}\n"
200 "MyClass.MyInnerClass.prototype.method3 = function() { return 3; }\n"
201 "MyClass.MyInnerClass.prototype.method4 = function() { return 4; }");
202 CheckFunctionName(script, "return 1", "MyClass.method1");
203 CheckFunctionName(script, "return 2", "MyClass.method2");
204 CheckFunctionName(script, "return 3", "MyClass.MyInnerClass.method3");
205 CheckFunctionName(script, "return 4", "MyClass.MyInnerClass.method4");
206}
207
208
209TEST(ObjectLiteral) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000210 CcTest::InitializeVM();
211 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000212
213 v8::Handle<v8::Script> script = Compile(
214 "function MyClass() {}\n"
215 "MyClass.prototype = {\n"
216 " method1: function() { return 1; },\n"
217 " method2: function() { return 2; } }");
218 CheckFunctionName(script, "return 1", "MyClass.method1");
219 CheckFunctionName(script, "return 2", "MyClass.method2");
220}
221
222
223TEST(AsParameter) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000224 CcTest::InitializeVM();
225 v8::HandleScope scope(CcTest::isolate());
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000226
227 v8::Handle<v8::Script> script = Compile(
228 "function f1(a) { return a(); }\n"
229 "function f2(a, b) { return a() + b(); }\n"
230 "var result1 = f1(function() { return 1; })\n"
231 "var result2 = f2(function() { return 2; }, function() { return 3; })");
232 // Can't infer names here.
233 CheckFunctionName(script, "return 1", "");
234 CheckFunctionName(script, "return 2", "");
235 CheckFunctionName(script, "return 3", "");
236}
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000237
238
239TEST(MultipleFuncsConditional) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000240 CcTest::InitializeVM();
241 v8::HandleScope scope(CcTest::isolate());
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000242
243 v8::Handle<v8::Script> script = Compile(
244 "fun1 = 0 ?\n"
245 " function() { return 1; } :\n"
246 " function() { return 2; }");
247 CheckFunctionName(script, "return 1", "fun1");
248 CheckFunctionName(script, "return 2", "fun1");
249}
250
251
252TEST(MultipleFuncsInLiteral) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000253 CcTest::InitializeVM();
254 v8::HandleScope scope(CcTest::isolate());
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000255
256 v8::Handle<v8::Script> script = Compile(
257 "function MyClass() {}\n"
258 "MyClass.prototype = {\n"
259 " method1: 0 ? function() { return 1; } :\n"
260 " function() { return 2; } }");
261 CheckFunctionName(script, "return 1", "MyClass.method1");
262 CheckFunctionName(script, "return 2", "MyClass.method1");
263}
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000264
265
266// See http://code.google.com/p/v8/issues/detail?id=380
267TEST(Issue380) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000268 CcTest::InitializeVM();
269 v8::HandleScope scope(CcTest::isolate());
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000270
271 v8::Handle<v8::Script> script = Compile(
272 "function a() {\n"
273 "var result = function(p,a,c,k,e,d)"
274 "{return p}(\"if blah blah\",62,1976,\'a|b\'.split(\'|\'),0,{})\n"
275 "}");
276 CheckFunctionName(script, "return p", "");
277}
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000278
279
280TEST(MultipleAssignments) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000281 CcTest::InitializeVM();
282 v8::HandleScope scope(CcTest::isolate());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000283
284 v8::Handle<v8::Script> script = Compile(
ager@chromium.org04921a82011-06-27 13:21:41 +0000285 "var fun1 = fun2 = function () { return 1; }\n"
286 "var bar1 = bar2 = bar3 = function () { return 2; }\n"
287 "foo1 = foo2 = function () { return 3; }\n"
288 "baz1 = baz2 = baz3 = function () { return 4; }");
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000289 CheckFunctionName(script, "return 1", "fun2");
ager@chromium.org04921a82011-06-27 13:21:41 +0000290 CheckFunctionName(script, "return 2", "bar3");
291 CheckFunctionName(script, "return 3", "foo2");
292 CheckFunctionName(script, "return 4", "baz3");
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000293}
294
295
ager@chromium.org04921a82011-06-27 13:21:41 +0000296TEST(AsConstructorParameter) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000297 CcTest::InitializeVM();
298 v8::HandleScope scope(CcTest::isolate());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000299
300 v8::Handle<v8::Script> script = Compile(
301 "function Foo() {}\n"
ager@chromium.org04921a82011-06-27 13:21:41 +0000302 "var foo = new Foo(function() { return 1; })\n"
303 "var bar = new Foo(function() { return 2; }, function() { return 3; })");
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000304 CheckFunctionName(script, "return 1", "");
ager@chromium.org04921a82011-06-27 13:21:41 +0000305 CheckFunctionName(script, "return 2", "");
306 CheckFunctionName(script, "return 3", "");
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000307}
308
309
310TEST(FactoryHashmap) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000311 CcTest::InitializeVM();
312 v8::HandleScope scope(CcTest::isolate());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000313
314 v8::Handle<v8::Script> script = Compile(
315 "function createMyObj() {\n"
316 " var obj = {};\n"
317 " obj[\"method1\"] = function() { return 1; }\n"
318 " obj[\"method2\"] = function() { return 2; }\n"
319 " return obj;\n"
320 "}");
321 CheckFunctionName(script, "return 1", "obj.method1");
322 CheckFunctionName(script, "return 2", "obj.method2");
323}
324
325
326TEST(FactoryHashmapVariable) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000327 CcTest::InitializeVM();
328 v8::HandleScope scope(CcTest::isolate());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000329
330 v8::Handle<v8::Script> script = Compile(
331 "function createMyObj() {\n"
332 " var obj = {};\n"
333 " var methodName = \"method1\";\n"
334 " obj[methodName] = function() { return 1; }\n"
335 " methodName = \"method2\";\n"
336 " obj[methodName] = function() { return 2; }\n"
337 " return obj;\n"
338 "}");
339 // Can't infer function names statically.
340 CheckFunctionName(script, "return 1", "obj.(anonymous function)");
341 CheckFunctionName(script, "return 2", "obj.(anonymous function)");
342}
343
344
345TEST(FactoryHashmapConditional) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000346 CcTest::InitializeVM();
347 v8::HandleScope scope(CcTest::isolate());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000348
349 v8::Handle<v8::Script> script = Compile(
350 "function createMyObj() {\n"
351 " var obj = {};\n"
352 " obj[0 ? \"method1\" : \"method2\"] = function() { return 1; }\n"
353 " return obj;\n"
354 "}");
355 // Can't infer the function name statically.
356 CheckFunctionName(script, "return 1", "obj.(anonymous function)");
357}
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000358
359
360TEST(GlobalAssignmentAndCall) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000361 CcTest::InitializeVM();
362 v8::HandleScope scope(CcTest::isolate());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000363
364 v8::Handle<v8::Script> script = Compile(
365 "var Foo = function() {\n"
366 " return 1;\n"
367 "}();\n"
368 "var Baz = Bar = function() {\n"
369 " return 2;\n"
370 "}");
371 // The inferred name is empty, because this is an assignment of a result.
372 CheckFunctionName(script, "return 1", "");
373 // See MultipleAssignments test.
374 CheckFunctionName(script, "return 2", "Bar");
375}
376
377
378TEST(AssignmentAndCall) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000379 CcTest::InitializeVM();
380 v8::HandleScope scope(CcTest::isolate());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000381
382 v8::Handle<v8::Script> script = Compile(
383 "(function Enclosing() {\n"
384 " var Foo;\n"
385 " Foo = function() {\n"
386 " return 1;\n"
387 " }();\n"
388 " var Baz = Bar = function() {\n"
389 " return 2;\n"
390 " }\n"
391 "})();");
392 // The inferred name is empty, because this is an assignment of a result.
393 CheckFunctionName(script, "return 1", "");
394 // See MultipleAssignments test.
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000395 // TODO(2276): Lazy compiling the enclosing outer closure would yield
396 // in "Enclosing.Bar" being the inferred name here.
397 CheckFunctionName(script, "return 2", "Bar");
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000398}
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000399
400
401TEST(MethodAssignmentInAnonymousFunctionCall) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000402 CcTest::InitializeVM();
403 v8::HandleScope scope(CcTest::isolate());
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000404
405 v8::Handle<v8::Script> script = Compile(
406 "(function () {\n"
407 " var EventSource = function () { };\n"
408 " EventSource.prototype.addListener = function () {\n"
409 " return 2012;\n"
410 " };\n"
411 " this.PublicEventSource = EventSource;\n"
412 "})();");
413 CheckFunctionName(script, "return 2012", "EventSource.addListener");
414}
415
416
417TEST(ReturnAnonymousFunction) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000418 CcTest::InitializeVM();
419 v8::HandleScope scope(CcTest::isolate());
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000420
421 v8::Handle<v8::Script> script = Compile(
422 "(function() {\n"
423 " function wrapCode() {\n"
424 " return function () {\n"
425 " return 2012;\n"
426 " };\n"
427 " };\n"
428 " var foo = 10;\n"
429 " function f() {\n"
430 " return wrapCode();\n"
431 " }\n"
432 " this.ref = f;\n"
433 "})()");
434 script->Run();
435 CheckFunctionName(script, "return 2012", "");
436}