Line data Source code
1 : // Copyright 2016 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 : // Test specific cases of the lazy/eager-parse decision.
6 : //
7 : // Note that presently most unit tests for parsing are found in
8 : // cctest/test-parsing.cc.
9 :
10 : #include <unordered_map>
11 :
12 : #include "include/v8.h"
13 : #include "src/api-inl.h"
14 : #include "src/handles-inl.h"
15 : #include "src/isolate.h"
16 : #include "src/objects-inl.h"
17 : #include "src/objects/shared-function-info-inl.h"
18 : #include "src/utils.h"
19 :
20 : #include "test/cctest/cctest.h"
21 :
22 : namespace v8 {
23 : namespace internal {
24 :
25 : namespace {
26 :
27 : // Record the 'compiled' state of all top level functions.
28 15 : void GetTopLevelFunctionInfo(
29 : v8::Local<v8::Script> script,
30 : std::unordered_map<std::string, bool>* is_compiled) {
31 : // Get the v8::internal::Script object from the API v8::Script.
32 : // The API object 'wraps' the compiled top-level function, not the i::Script.
33 : Handle<JSFunction> toplevel_fn = v8::Utils::OpenHandle(*script);
34 : SharedFunctionInfo::ScriptIterator iterator(
35 30 : toplevel_fn->GetIsolate(), Script::cast(toplevel_fn->shared()->script()));
36 :
37 180 : for (SharedFunctionInfo shared = iterator.Next(); !shared.is_null();
38 : shared = iterator.Next()) {
39 75 : std::unique_ptr<char[]> name = String::cast(shared->Name())->ToCString();
40 225 : is_compiled->insert(std::make_pair(name.get(), shared->is_compiled()));
41 : }
42 15 : }
43 :
44 : } // anonymous namespace
45 :
46 26644 : TEST(GetTopLevelFunctionInfo) {
47 5 : if (!FLAG_lazy) return;
48 :
49 : Isolate* isolate = CcTest::i_isolate();
50 : HandleScope scope(isolate);
51 5 : LocalContext env;
52 :
53 5 : const char src[] = "function foo() { var a; }\n";
54 : std::unordered_map<std::string, bool> is_compiled;
55 5 : GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
56 :
57 : // Test that our helper function GetTopLevelFunctionInfo does what it claims:
58 : DCHECK(is_compiled.find("foo") != is_compiled.end());
59 : DCHECK(is_compiled.find("bar") == is_compiled.end());
60 : }
61 :
62 26644 : TEST(EagerlyCompileImmediateUseFunctions) {
63 5 : if (!FLAG_lazy) return;
64 :
65 : Isolate* isolate = CcTest::i_isolate();
66 : HandleScope scope(isolate);
67 5 : LocalContext env;
68 :
69 : // Test parenthesized, exclaimed, and regular functions. Make sure these
70 : // occur both intermixed and after each other, to make sure the 'reset'
71 : // mechanism works.
72 : const char src[] =
73 : "function normal() { var a; }\n" // Normal: Should lazy parse.
74 : "(function parenthesized() { var b; })()\n" // Parenthesized: Pre-parse.
75 : "!function exclaimed() { var c; }() \n" // Exclaimed: Pre-parse.
76 : "function normal2() { var d; }\n"
77 : "(function parenthesized2() { var e; })()\n"
78 : "function normal3() { var f; }\n"
79 : "!function exclaimed2() { var g; }() \n"
80 5 : "function normal4() { var h; }\n";
81 :
82 : std::unordered_map<std::string, bool> is_compiled;
83 5 : GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
84 :
85 : DCHECK(is_compiled["parenthesized"]);
86 : DCHECK(is_compiled["parenthesized2"]);
87 : DCHECK(is_compiled["exclaimed"]);
88 : DCHECK(is_compiled["exclaimed2"]);
89 : DCHECK(!is_compiled["normal"]);
90 : DCHECK(!is_compiled["normal2"]);
91 : DCHECK(!is_compiled["normal3"]);
92 : DCHECK(!is_compiled["normal4"]);
93 : }
94 :
95 26644 : TEST(CommaFunctionSequence) {
96 5 : if (!FLAG_lazy) return;
97 :
98 : Isolate* isolate = CcTest::i_isolate();
99 : HandleScope scope(isolate);
100 5 : LocalContext env;
101 :
102 5 : const char src[] = "!function a(){}(),function b(){}(),function c(){}();";
103 : std::unordered_map<std::string, bool> is_compiled;
104 5 : GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
105 :
106 : DCHECK(is_compiled["a"]);
107 : DCHECK(is_compiled["b"]);
108 : DCHECK(is_compiled["c"]);
109 : }
110 :
111 : } // namespace internal
112 79917 : } // namespace v8
|