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 20namespace v8 { 21namespace internal { 22namespace parsing { 23 24namespace { 25 26void MaybeReportStatistics(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 40bool 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(isolate->main_thread_local_isolate(), info, script); 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 MaybeReportStatistics(info, script, isolate, &parser, mode); 61 return info->literal() != nullptr; 62} 63 64bool ParseProgram(ParseInfo* info, Handle<Script> script, Isolate* isolate, 65 ReportStatisticsMode mode) { 66 return ParseProgram(info, script, kNullMaybeHandle, isolate, mode); 67} 68 69bool 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(isolate->main_thread_local_isolate(), info, script); 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 MaybeReportStatistics(info, script, isolate, &parser, mode); 92 return info->literal() != nullptr; 93} 94 95bool 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