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 | |
17 | namespace v8 { |
18 | namespace internal { |
19 | namespace parsing { |
20 | |
21 | bool 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 | |
55 | bool 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 | |
92 | bool 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 | |