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