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