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/objects-inl.h"
11#include "src/parsing/parse-info.h"
12#include "src/parsing/parser.h"
13#include "src/parsing/scanner-character-streams.h"
14#include "src/vm-state-inl.h"
15#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
16
17namespace v8 {
18namespace internal {
19namespace parsing {
20
21bool ParseProgram(ParseInfo* info, Isolate* isolate) {
22 DCHECK(info->is_toplevel());
23 DCHECK_NULL(info->literal());
24
25 VMState<PARSER> state(isolate);
26
27 // Create a character stream for the parser.
28 Handle<String> source(String::cast(info->script()->source()), isolate);
29 isolate->counters()->total_parse_size()->Increment(source->length());
30 std::unique_ptr<Utf16CharacterStream> stream(
31 ScannerStream::For(isolate, source));
32 info->set_character_stream(std::move(stream));
33
34 Parser parser(info);
35
36 FunctionLiteral* result = nullptr;
37 // Ok to use Isolate here; this function is only called in the main thread.
38 DCHECK(parser.parsing_on_main_thread_);
39
40 result = parser.ParseProgram(isolate, info);
41 info->set_literal(result);
42 if (result == nullptr) {
43 info->pending_error_handler()->ReportErrors(isolate, info->script(),
44 info->ast_value_factory());
45 } else {
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 parser.UpdateStatistics(isolate, info->script());
52 return (result != nullptr);
53}
54
55bool ParseFunction(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
56 Isolate* isolate) {
57 DCHECK(!info->is_toplevel());
58 DCHECK(!shared_info.is_null());
59 DCHECK_NULL(info->literal());
60
61 // Create a character stream for the parser.
62 Handle<String> source(String::cast(info->script()->source()), isolate);
63 isolate->counters()->total_parse_size()->Increment(source->length());
64 std::unique_ptr<Utf16CharacterStream> stream(
65 ScannerStream::For(isolate, source, shared_info->StartPosition(),
66 shared_info->EndPosition()));
67 info->set_character_stream(std::move(stream));
68
69 VMState<PARSER> state(isolate);
70
71 Parser parser(info);
72
73 FunctionLiteral* result = nullptr;
74 // Ok to use Isolate here; this function is only called in the main thread.
75 DCHECK(parser.parsing_on_main_thread_);
76
77 result = parser.ParseFunction(isolate, info, shared_info);
78 info->set_literal(result);
79 if (result == nullptr) {
80 info->pending_error_handler()->ReportErrors(isolate, info->script(),
81 info->ast_value_factory());
82 } else {
83 info->ast_value_factory()->Internalize(isolate);
84 if (info->is_eval()) {
85 info->set_allow_eval_cache(parser.allow_eval_cache());
86 }
87 }
88 parser.UpdateStatistics(isolate, info->script());
89 return (result != nullptr);
90}
91
92bool ParseAny(ParseInfo* info, Handle<SharedFunctionInfo> shared_info,
93 Isolate* isolate) {
94 DCHECK(!shared_info.is_null());
95 return info->is_toplevel() ? ParseProgram(info, isolate)
96 : ParseFunction(info, shared_info, isolate);
97}
98
99} // namespace parsing
100} // namespace internal
101} // namespace v8
102