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 #include "src/parsing/parsing.h"
6
7 #include <memory>
8
9 #include "src/ast/ast.h"
10 #include "src/base/v8-fallthrough.h"
11 #include "src/execution/vm-state-inl.h"
12 #include "src/handles/maybe-handles.h"
13 #include "src/objects/objects-inl.h"
14 #include "src/parsing/parse-info.h"
15 #include "src/parsing/parser.h"
16 #include "src/parsing/rewriter.h"
17 #include "src/parsing/scanner-character-streams.h"
18 #include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
19
20 namespace v8 {
21 namespace internal {
22 namespace parsing {
23
24 namespace {
25
MaybeReportErrorsAndStatistics(ParseInfo * info,Handle<Script> script,Isolate * isolate,Parser * parser,ReportStatisticsMode mode)26 void MaybeReportErrorsAndStatistics(ParseInfo* info, Handle<Script> script,
27 Isolate* isolate, Parser* parser,
28 ReportStatisticsMode mode) {
29 switch (mode) {
30 case ReportStatisticsMode::kYes:
31 parser->UpdateStatistics(isolate, script);
32 break;
33 case ReportStatisticsMode::kNo:
34 break;
35 }
36 }
37
38 } // namespace
39
ParseProgram(ParseInfo * info,Handle<Script> script,MaybeHandle<ScopeInfo> maybe_outer_scope_info,Isolate * isolate,ReportStatisticsMode mode)40 bool ParseProgram(ParseInfo* info, Handle<Script> script,
41 MaybeHandle<ScopeInfo> maybe_outer_scope_info,
42 Isolate* isolate, ReportStatisticsMode mode) {
43 DCHECK(info->flags().is_toplevel());
44 DCHECK_NULL(info->literal());
45
46 VMState<PARSER> state(isolate);
47
48 // Create a character stream for the parser.
49 Handle<String> source(String::cast(script->source()), isolate);
50 isolate->counters()->total_parse_size()->Increment(source->length());
51 std::unique_ptr<Utf16CharacterStream> stream(
52 ScannerStream::For(isolate, source));
53 info->set_character_stream(std::move(stream));
54
55 Parser parser(info);
56
57 // Ok to use Isolate here; this function is only called in the main thread.
58 DCHECK(parser.parsing_on_main_thread_);
59 parser.ParseProgram(isolate, script, info, maybe_outer_scope_info);
60 MaybeReportErrorsAndStatistics(info, script, isolate, &parser, mode);
61 return info->literal() != nullptr;
62 }
63
ParseProgram(ParseInfo * info,Handle<Script> script,Isolate * isolate,ReportStatisticsMode mode)64 bool ParseProgram(ParseInfo* info, Handle<Script> script, Isolate* isolate,
65 ReportStatisticsMode mode) {
66 return ParseProgram(info, script, kNullMaybeHandle, isolate, mode);
67 }
68
ParseFunction(ParseInfo * info,Handle<SharedFunctionInfo> shared_info,Isolate * isolate,ReportStatisticsMode mode)69 bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
70 Isolate* isolate, ReportStatisticsMode mode) {
71 DCHECK(!info->flags().is_toplevel());
72 DCHECK(!shared_info.is_null());
73 DCHECK_NULL(info->literal());
74
75 VMState<PARSER> state(isolate);
76
77 // Create a character stream for the parser.
78 Handle<Script> script(Script::cast(shared_info->script()), isolate);
79 Handle<String> source(String::cast(script->source()), isolate);
80 isolate->counters()->total_parse_size()->Increment(source->length());
81 std::unique_ptr<Utf16CharacterStream> stream(
82 ScannerStream::For(isolate, source, shared_info->StartPosition(),
83 shared_info->EndPosition()));
84 info->set_character_stream(std::move(stream));
85
86 Parser parser(info);
87
88 // Ok to use Isolate here; this function is only called in the main thread.
89 DCHECK(parser.parsing_on_main_thread_);
90 parser.ParseFunction(isolate, info, shared_info);
91 MaybeReportErrorsAndStatistics(info, script, isolate, &parser, mode);
92 return info->literal() != nullptr;
93 }
94
ParseAny(ParseInfo * info,Handle<SharedFunctionInfo> shared_info,Isolate * isolate,ReportStatisticsMode mode)95 bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
96 Isolate* isolate, ReportStatisticsMode mode) {
97 DCHECK(!shared_info.is_null());
98 if (info->flags().is_toplevel()) {
99 MaybeHandle<ScopeInfo> maybe_outer_scope_info;
100 if (shared_info->HasOuterScopeInfo()) {
101 maybe_outer_scope_info =
102 handle(shared_info->GetOuterScopeInfo(), isolate);
103 }
104 return ParseProgram(info,
105 handle(Script::cast(shared_info->script()), isolate),
106 maybe_outer_scope_info, isolate, mode);
107 }
108 return ParseFunction(info, shared_info, isolate, mode);
109 }
110
111 } // namespace parsing
112 } // namespace internal
113 } // namespace v8
114