The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / test / cctest / test-func-name-inference.cc @ f230a1cf

History | View | Annotate | Download (15 KB)

1
// Copyright 2011 the V8 project authors. All rights reserved.
2
// 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

    
28

    
29
#include "v8.h"
30

    
31
#include "api.h"
32
#include "debug.h"
33
#include "runtime.h"
34
#include "cctest.h"
35

    
36

    
37
using ::v8::internal::CStrVector;
38
using ::v8::internal::Factory;
39
using ::v8::internal::Handle;
40
using ::v8::internal::Heap;
41
using ::v8::internal::Isolate;
42
using ::v8::internal::JSFunction;
43
using ::v8::internal::Object;
44
using ::v8::internal::Runtime;
45
using ::v8::internal::Script;
46
using ::v8::internal::SmartArrayPointer;
47
using ::v8::internal::SharedFunctionInfo;
48
using ::v8::internal::String;
49

    
50

    
51
static void CheckFunctionName(v8::Handle<v8::Script> script,
52
                              const char* func_pos_src,
53
                              const char* ref_inferred_name) {
54
  Isolate* isolate = CcTest::i_isolate();
55
  Factory* factory = isolate->factory();
56

    
57
  // Get script source.
58
  Handle<Object> obj = v8::Utils::OpenHandle(*script);
59
  Handle<SharedFunctionInfo> shared_function;
60
  if (obj->IsSharedFunctionInfo()) {
61
    shared_function =
62
        Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(*obj));
63
  } else {
64
    shared_function =
65
        Handle<SharedFunctionInfo>(JSFunction::cast(*obj)->shared());
66
  }
67
  Handle<Script> i_script(Script::cast(shared_function->script()));
68
  CHECK(i_script->source()->IsString());
69
  Handle<String> script_src(String::cast(i_script->source()));
70

    
71
  // Find the position of a given func source substring in the source.
72
  Handle<String> func_pos_str =
73
      factory->NewStringFromAscii(CStrVector(func_pos_src));
74
  int func_pos = Runtime::StringMatch(isolate,
75
                                      script_src,
76
                                      func_pos_str,
77
                                      0);
78
  CHECK_NE(0, func_pos);
79

    
80
#ifdef ENABLE_DEBUGGER_SUPPORT
81
  // Obtain SharedFunctionInfo for the function.
82
  isolate->debug()->PrepareForBreakPoints();
83
  Object* shared_func_info_ptr =
84
      isolate->debug()->FindSharedFunctionInfoInScript(i_script, func_pos);
85
  CHECK(shared_func_info_ptr != CcTest::heap()->undefined_value());
86
  Handle<SharedFunctionInfo> shared_func_info(
87
      SharedFunctionInfo::cast(shared_func_info_ptr));
88

    
89
  // Verify inferred function name.
90
  SmartArrayPointer<char> inferred_name =
91
      shared_func_info->inferred_name()->ToCString();
92
  CHECK_EQ(ref_inferred_name, *inferred_name);
93
#endif  // ENABLE_DEBUGGER_SUPPORT
94
}
95

    
96

    
97
static v8::Handle<v8::Script> Compile(const char* src) {
98
  return v8::Script::Compile(v8::String::New(src));
99
}
100

    
101

    
102
TEST(GlobalProperty) {
103
  CcTest::InitializeVM();
104
  v8::HandleScope scope(CcTest::isolate());
105

    
106
  v8::Handle<v8::Script> script = Compile(
107
      "fun1 = function() { return 1; }\n"
108
      "fun2 = function() { return 2; }\n");
109
  CheckFunctionName(script, "return 1", "fun1");
110
  CheckFunctionName(script, "return 2", "fun2");
111
}
112

    
113

    
114
TEST(GlobalVar) {
115
  CcTest::InitializeVM();
116
  v8::HandleScope scope(CcTest::isolate());
117

    
118
  v8::Handle<v8::Script> script = Compile(
119
      "var fun1 = function() { return 1; }\n"
120
      "var fun2 = function() { return 2; }\n");
121
  CheckFunctionName(script, "return 1", "fun1");
122
  CheckFunctionName(script, "return 2", "fun2");
123
}
124

    
125

    
126
TEST(LocalVar) {
127
  CcTest::InitializeVM();
128
  v8::HandleScope scope(CcTest::isolate());
129

    
130
  v8::Handle<v8::Script> script = Compile(
131
      "function outer() {\n"
132
      "  var fun1 = function() { return 1; }\n"
133
      "  var fun2 = function() { return 2; }\n"
134
      "}");
135
  CheckFunctionName(script, "return 1", "fun1");
136
  CheckFunctionName(script, "return 2", "fun2");
137
}
138

    
139

    
140
TEST(InConstructor) {
141
  CcTest::InitializeVM();
142
  v8::HandleScope scope(CcTest::isolate());
143

    
144
  v8::Handle<v8::Script> script = Compile(
145
      "function MyClass() {\n"
146
      "  this.method1 = function() { return 1; }\n"
147
      "  this.method2 = function() { return 2; }\n"
148
      "}");
149
  CheckFunctionName(script, "return 1", "MyClass.method1");
150
  CheckFunctionName(script, "return 2", "MyClass.method2");
151
}
152

    
153

    
154
TEST(Factory) {
155
  CcTest::InitializeVM();
156
  v8::HandleScope scope(CcTest::isolate());
157

    
158
  v8::Handle<v8::Script> script = Compile(
159
      "function createMyObj() {\n"
160
      "  var obj = {};\n"
161
      "  obj.method1 = function() { return 1; }\n"
162
      "  obj.method2 = function() { return 2; }\n"
163
      "  return obj;\n"
164
      "}");
165
  CheckFunctionName(script, "return 1", "obj.method1");
166
  CheckFunctionName(script, "return 2", "obj.method2");
167
}
168

    
169

    
170
TEST(Static) {
171
  CcTest::InitializeVM();
172
  v8::HandleScope scope(CcTest::isolate());
173

    
174
  v8::Handle<v8::Script> script = Compile(
175
      "function MyClass() {}\n"
176
      "MyClass.static1 = function() { return 1; }\n"
177
      "MyClass.static2 = function() { return 2; }\n"
178
      "MyClass.MyInnerClass = {}\n"
179
      "MyClass.MyInnerClass.static3 = function() { return 3; }\n"
180
      "MyClass.MyInnerClass.static4 = function() { return 4; }");
181
  CheckFunctionName(script, "return 1", "MyClass.static1");
182
  CheckFunctionName(script, "return 2", "MyClass.static2");
183
  CheckFunctionName(script, "return 3", "MyClass.MyInnerClass.static3");
184
  CheckFunctionName(script, "return 4", "MyClass.MyInnerClass.static4");
185
}
186

    
187

    
188
TEST(Prototype) {
189
  CcTest::InitializeVM();
190
  v8::HandleScope scope(CcTest::isolate());
191

    
192
  v8::Handle<v8::Script> script = Compile(
193
      "function MyClass() {}\n"
194
      "MyClass.prototype.method1 = function() { return 1; }\n"
195
      "MyClass.prototype.method2 = function() { return 2; }\n"
196
      "MyClass.MyInnerClass = function() {}\n"
197
      "MyClass.MyInnerClass.prototype.method3 = function() { return 3; }\n"
198
      "MyClass.MyInnerClass.prototype.method4 = function() { return 4; }");
199
  CheckFunctionName(script, "return 1", "MyClass.method1");
200
  CheckFunctionName(script, "return 2", "MyClass.method2");
201
  CheckFunctionName(script, "return 3", "MyClass.MyInnerClass.method3");
202
  CheckFunctionName(script, "return 4", "MyClass.MyInnerClass.method4");
203
}
204

    
205

    
206
TEST(ObjectLiteral) {
207
  CcTest::InitializeVM();
208
  v8::HandleScope scope(CcTest::isolate());
209

    
210
  v8::Handle<v8::Script> script = Compile(
211
      "function MyClass() {}\n"
212
      "MyClass.prototype = {\n"
213
      "  method1: function() { return 1; },\n"
214
      "  method2: function() { return 2; } }");
215
  CheckFunctionName(script, "return 1", "MyClass.method1");
216
  CheckFunctionName(script, "return 2", "MyClass.method2");
217
}
218

    
219

    
220
TEST(AsParameter) {
221
  CcTest::InitializeVM();
222
  v8::HandleScope scope(CcTest::isolate());
223

    
224
  v8::Handle<v8::Script> script = Compile(
225
      "function f1(a) { return a(); }\n"
226
      "function f2(a, b) { return a() + b(); }\n"
227
      "var result1 = f1(function() { return 1; })\n"
228
      "var result2 = f2(function() { return 2; }, function() { return 3; })");
229
  // Can't infer names here.
230
  CheckFunctionName(script, "return 1", "");
231
  CheckFunctionName(script, "return 2", "");
232
  CheckFunctionName(script, "return 3", "");
233
}
234

    
235

    
236
TEST(MultipleFuncsConditional) {
237
  CcTest::InitializeVM();
238
  v8::HandleScope scope(CcTest::isolate());
239

    
240
  v8::Handle<v8::Script> script = Compile(
241
      "fun1 = 0 ?\n"
242
      "    function() { return 1; } :\n"
243
      "    function() { return 2; }");
244
  CheckFunctionName(script, "return 1", "fun1");
245
  CheckFunctionName(script, "return 2", "fun1");
246
}
247

    
248

    
249
TEST(MultipleFuncsInLiteral) {
250
  CcTest::InitializeVM();
251
  v8::HandleScope scope(CcTest::isolate());
252

    
253
  v8::Handle<v8::Script> script = Compile(
254
      "function MyClass() {}\n"
255
      "MyClass.prototype = {\n"
256
      "  method1: 0 ? function() { return 1; } :\n"
257
      "               function() { return 2; } }");
258
  CheckFunctionName(script, "return 1", "MyClass.method1");
259
  CheckFunctionName(script, "return 2", "MyClass.method1");
260
}
261

    
262

    
263
TEST(AnonymousInAnonymousClosure1) {
264
  CcTest::InitializeVM();
265
  v8::HandleScope scope(CcTest::isolate());
266

    
267
  v8::Handle<v8::Script> script = Compile(
268
      "(function() {\n"
269
      "  (function() {\n"
270
      "      var a = 1;\n"
271
      "      return;\n"
272
      "  })();\n"
273
      "  var b = function() {\n"
274
      "      var c = 1;\n"
275
      "      return;\n"
276
      "  };\n"
277
      "})();");
278
  CheckFunctionName(script, "return", "");
279
}
280

    
281

    
282
TEST(AnonymousInAnonymousClosure2) {
283
  CcTest::InitializeVM();
284
  v8::HandleScope scope(CcTest::isolate());
285

    
286
  v8::Handle<v8::Script> script = Compile(
287
      "(function() {\n"
288
      "  (function() {\n"
289
      "      var a = 1;\n"
290
      "      return;\n"
291
      "  })();\n"
292
      "  var c = 1;\n"
293
      "})();");
294
  CheckFunctionName(script, "return", "");
295
}
296

    
297

    
298
TEST(NamedInAnonymousClosure) {
299
  CcTest::InitializeVM();
300
  v8::HandleScope scope(CcTest::isolate());
301

    
302
  v8::Handle<v8::Script> script = Compile(
303
      "var foo = function() {\n"
304
      "  (function named() {\n"
305
      "      var a = 1;\n"
306
      "  })();\n"
307
      "  var c = 1;\n"
308
      "  return;\n"
309
      "};");
310
  CheckFunctionName(script, "return", "foo");
311
}
312

    
313

    
314
// See http://code.google.com/p/v8/issues/detail?id=380
315
TEST(Issue380) {
316
  CcTest::InitializeVM();
317
  v8::HandleScope scope(CcTest::isolate());
318

    
319
  v8::Handle<v8::Script> script = Compile(
320
      "function a() {\n"
321
      "var result = function(p,a,c,k,e,d)"
322
      "{return p}(\"if blah blah\",62,1976,\'a|b\'.split(\'|\'),0,{})\n"
323
      "}");
324
  CheckFunctionName(script, "return p", "");
325
}
326

    
327

    
328
TEST(MultipleAssignments) {
329
  CcTest::InitializeVM();
330
  v8::HandleScope scope(CcTest::isolate());
331

    
332
  v8::Handle<v8::Script> script = Compile(
333
      "var fun1 = fun2 = function () { return 1; }\n"
334
      "var bar1 = bar2 = bar3 = function () { return 2; }\n"
335
      "foo1 = foo2 = function () { return 3; }\n"
336
      "baz1 = baz2 = baz3 = function () { return 4; }");
337
  CheckFunctionName(script, "return 1", "fun2");
338
  CheckFunctionName(script, "return 2", "bar3");
339
  CheckFunctionName(script, "return 3", "foo2");
340
  CheckFunctionName(script, "return 4", "baz3");
341
}
342

    
343

    
344
TEST(AsConstructorParameter) {
345
  CcTest::InitializeVM();
346
  v8::HandleScope scope(CcTest::isolate());
347

    
348
  v8::Handle<v8::Script> script = Compile(
349
      "function Foo() {}\n"
350
      "var foo = new Foo(function() { return 1; })\n"
351
      "var bar = new Foo(function() { return 2; }, function() { return 3; })");
352
  CheckFunctionName(script, "return 1", "");
353
  CheckFunctionName(script, "return 2", "");
354
  CheckFunctionName(script, "return 3", "");
355
}
356

    
357

    
358
TEST(FactoryHashmap) {
359
  CcTest::InitializeVM();
360
  v8::HandleScope scope(CcTest::isolate());
361

    
362
  v8::Handle<v8::Script> script = Compile(
363
      "function createMyObj() {\n"
364
      "  var obj = {};\n"
365
      "  obj[\"method1\"] = function() { return 1; }\n"
366
      "  obj[\"method2\"] = function() { return 2; }\n"
367
      "  return obj;\n"
368
      "}");
369
  CheckFunctionName(script, "return 1", "obj.method1");
370
  CheckFunctionName(script, "return 2", "obj.method2");
371
}
372

    
373

    
374
TEST(FactoryHashmapVariable) {
375
  CcTest::InitializeVM();
376
  v8::HandleScope scope(CcTest::isolate());
377

    
378
  v8::Handle<v8::Script> script = Compile(
379
      "function createMyObj() {\n"
380
      "  var obj = {};\n"
381
      "  var methodName = \"method1\";\n"
382
      "  obj[methodName] = function() { return 1; }\n"
383
      "  methodName = \"method2\";\n"
384
      "  obj[methodName] = function() { return 2; }\n"
385
      "  return obj;\n"
386
      "}");
387
  // Can't infer function names statically.
388
  CheckFunctionName(script, "return 1", "obj.(anonymous function)");
389
  CheckFunctionName(script, "return 2", "obj.(anonymous function)");
390
}
391

    
392

    
393
TEST(FactoryHashmapConditional) {
394
  CcTest::InitializeVM();
395
  v8::HandleScope scope(CcTest::isolate());
396

    
397
  v8::Handle<v8::Script> script = Compile(
398
      "function createMyObj() {\n"
399
      "  var obj = {};\n"
400
      "  obj[0 ? \"method1\" : \"method2\"] = function() { return 1; }\n"
401
      "  return obj;\n"
402
      "}");
403
  // Can't infer the function name statically.
404
  CheckFunctionName(script, "return 1", "obj.(anonymous function)");
405
}
406

    
407

    
408
TEST(GlobalAssignmentAndCall) {
409
  CcTest::InitializeVM();
410
  v8::HandleScope scope(CcTest::isolate());
411

    
412
  v8::Handle<v8::Script> script = Compile(
413
      "var Foo = function() {\n"
414
      "  return 1;\n"
415
      "}();\n"
416
      "var Baz = Bar = function() {\n"
417
      "  return 2;\n"
418
      "}");
419
  // The inferred name is empty, because this is an assignment of a result.
420
  CheckFunctionName(script, "return 1", "");
421
  // See MultipleAssignments test.
422
  CheckFunctionName(script, "return 2", "Bar");
423
}
424

    
425

    
426
TEST(AssignmentAndCall) {
427
  CcTest::InitializeVM();
428
  v8::HandleScope scope(CcTest::isolate());
429

    
430
  v8::Handle<v8::Script> script = Compile(
431
      "(function Enclosing() {\n"
432
      "  var Foo;\n"
433
      "  Foo = function() {\n"
434
      "    return 1;\n"
435
      "  }();\n"
436
      "  var Baz = Bar = function() {\n"
437
      "    return 2;\n"
438
      "  }\n"
439
      "})();");
440
  // The inferred name is empty, because this is an assignment of a result.
441
  CheckFunctionName(script, "return 1", "");
442
  // See MultipleAssignments test.
443
  // TODO(2276): Lazy compiling the enclosing outer closure would yield
444
  // in "Enclosing.Bar" being the inferred name here.
445
  CheckFunctionName(script, "return 2", "Bar");
446
}
447

    
448

    
449
TEST(MethodAssignmentInAnonymousFunctionCall) {
450
  CcTest::InitializeVM();
451
  v8::HandleScope scope(CcTest::isolate());
452

    
453
  v8::Handle<v8::Script> script = Compile(
454
      "(function () {\n"
455
      "    var EventSource = function () { };\n"
456
      "    EventSource.prototype.addListener = function () {\n"
457
      "        return 2012;\n"
458
      "    };\n"
459
      "    this.PublicEventSource = EventSource;\n"
460
      "})();");
461
  CheckFunctionName(script, "return 2012", "EventSource.addListener");
462
}
463

    
464

    
465
TEST(ReturnAnonymousFunction) {
466
  CcTest::InitializeVM();
467
  v8::HandleScope scope(CcTest::isolate());
468

    
469
  v8::Handle<v8::Script> script = Compile(
470
      "(function() {\n"
471
      "  function wrapCode() {\n"
472
      "    return function () {\n"
473
      "      return 2012;\n"
474
      "    };\n"
475
      "  };\n"
476
      "  var foo = 10;\n"
477
      "  function f() {\n"
478
      "    return wrapCode();\n"
479
      "  }\n"
480
      "  this.ref = f;\n"
481
      "})()");
482
  script->Run();
483
  CheckFunctionName(script, "return 2012", "");
484
}