OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PARSER_H_ | 5 #ifndef V8_PARSER_H_ |
6 #define V8_PARSER_H_ | 6 #define V8_PARSER_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/compiler.h" // For CachedDataMode | 10 #include "src/compiler.h" // For CachedDataMode |
11 #include "src/pending-compilation-error-handler.h" | 11 #include "src/pending-compilation-error-handler.h" |
12 #include "src/preparse-data.h" | 12 #include "src/preparse-data.h" |
13 #include "src/preparse-data-format.h" | 13 #include "src/preparse-data-format.h" |
14 #include "src/preparser.h" | 14 #include "src/preparser.h" |
15 #include "src/scopes.h" | 15 #include "src/scopes.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 class ScriptCompiler; | 18 class ScriptCompiler; |
19 | 19 |
20 namespace internal { | 20 namespace internal { |
21 | 21 |
22 class CompilationInfo; | |
23 class ParserLog; | 22 class ParserLog; |
24 class PositionStack; | 23 class PositionStack; |
25 class Target; | 24 class Target; |
26 | 25 |
26 // TODO(titzer): move this to preparse-data.h? | |
27 class ScriptData { | |
marja
2015/03/04 09:24:40
Can you put the added classes (ScriptData and Pars
titzer
2015/03/04 22:39:35
ScriptData probably should live somewhere else, bu
titzer
2015/03/05 20:18:30
I've moved ScriptData to preparse-data.h
| |
28 public: | |
29 ScriptData(const byte* data, int length); | |
30 ~ScriptData() { | |
31 if (owns_data_) DeleteArray(data_); | |
32 } | |
33 | |
34 const byte* data() const { return data_; } | |
35 int length() const { return length_; } | |
36 bool rejected() const { return rejected_; } | |
37 | |
38 void Reject() { rejected_ = true; } | |
39 | |
40 void AcquireDataOwnership() { | |
41 DCHECK(!owns_data_); | |
42 owns_data_ = true; | |
43 } | |
44 | |
45 void ReleaseDataOwnership() { | |
46 DCHECK(owns_data_); | |
47 owns_data_ = false; | |
48 } | |
49 | |
50 private: | |
51 bool owns_data_ : 1; | |
52 bool rejected_ : 1; | |
53 const byte* data_; | |
54 int length_; | |
55 | |
56 DISALLOW_COPY_AND_ASSIGN(ScriptData); | |
57 }; | |
58 | |
59 // Collects the data necessary to parse a function as well as the outcome | |
60 // of parsing, which includes an AST. | |
61 class ParseInfo { | |
62 public: | |
63 explicit ParseInfo(Zone* zone) { | |
64 memset(this, 0, sizeof(ParseInfo)); | |
65 zone_ = zone; | |
66 } | |
67 | |
68 ~ParseInfo() { DeleteAstValueFactory(); } | |
69 | |
70 void InitializeFromJSFunction(Handle<JSFunction> function); | |
71 void InitializeFromSharedFunctionInfo(Handle<SharedFunctionInfo> shared); | |
72 void InitializeFromScript(Handle<Script> script); | |
73 | |
74 // Various configuration flags for parsing. | |
75 enum Flag { | |
rossberg
2015/03/04 10:25:12
Can we make the enum private?
titzer
2015/03/04 22:39:35
Done.
| |
76 // ---------- Input flags --------------------------- | |
77 kToplevel = 1 << 0, | |
78 kLazy = 1 << 1, | |
79 kEval = 1 << 2, | |
80 kGlobal = 1 << 3, | |
81 kStrictMode = 1 << 4, | |
82 kStrongMode = 1 << 5, | |
83 kNative = 1 << 6, | |
84 kParseRestriction = 1 << 7, | |
85 kModule = 1 << 8, | |
86 kAllowLazyParsing = 1 << 9, | |
87 // ---------- Output flags -------------------------- | |
88 kThisHasUses = 1 << 10, | |
89 kAstValueFactoryOwned = 1 << 11 | |
90 }; | |
91 | |
92 // Convenience accessor methods for flags. | |
93 #define FLAG_ACCESSOR(flag, getter, setter) \ | |
94 bool getter() const { return GetFlag(flag); } \ | |
95 void setter() { SetFlag(flag); } \ | |
96 void setter(bool val) { SetFlag(flag, val); } | |
97 | |
98 FLAG_ACCESSOR(kToplevel, is_toplevel, set_toplevel) | |
99 FLAG_ACCESSOR(kLazy, is_lazy, set_lazy) | |
100 FLAG_ACCESSOR(kEval, is_eval, set_eval) | |
101 FLAG_ACCESSOR(kGlobal, is_global, set_global) | |
102 FLAG_ACCESSOR(kStrictMode, is_strict_mode, set_strict_mode) | |
103 FLAG_ACCESSOR(kStrongMode, is_strong_mode, set_strong_mode) | |
104 FLAG_ACCESSOR(kNative, is_native, set_native) | |
105 FLAG_ACCESSOR(kModule, is_module, set_module) | |
106 FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing) | |
107 FLAG_ACCESSOR(kThisHasUses, this_has_uses, set_this_has_uses) | |
108 FLAG_ACCESSOR(kAstValueFactoryOwned, ast_value_factory_owned, | |
109 set_ast_value_factory_owned) | |
110 | |
111 void set_parse_restriction(ParseRestriction restriction) { | |
112 SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION); | |
113 } | |
114 | |
115 ParseRestriction parse_restriction() const { | |
116 return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL | |
117 : NO_PARSE_RESTRICTION; | |
118 } | |
119 | |
120 #undef FLAG_ACCESSOR | |
121 | |
122 Zone* zone() { return zone_; } | |
123 | |
124 ScriptCompiler::ExternalSourceStream* source_stream() { | |
125 return source_stream_; | |
126 } | |
127 void set_source_stream(ScriptCompiler::ExternalSourceStream* source_stream) { | |
128 source_stream_ = source_stream; | |
129 } | |
130 | |
131 ScriptCompiler::StreamedSource::Encoding source_stream_encoding() { | |
132 return source_stream_encoding_; | |
133 } | |
134 void set_source_stream_encoding( | |
135 ScriptCompiler::StreamedSource::Encoding source_stream_encoding) { | |
136 source_stream_encoding_ = source_stream_encoding; | |
137 } | |
138 | |
139 v8::Extension* extension() { return extension_; } | |
140 void set_extension(v8::Extension* extension) { extension_ = extension; } | |
141 | |
142 ScriptData** cached_data() { return cached_data_; } | |
143 void set_cached_data(ScriptData** cached_data) { cached_data_ = cached_data; } | |
144 | |
145 ScriptCompiler::CompileOptions compile_options() { return compile_options_; } | |
146 void set_compile_options(ScriptCompiler::CompileOptions compile_options) { | |
147 compile_options_ = compile_options; | |
148 } | |
149 | |
150 Scope* script_scope() { return script_scope_; } | |
151 void set_script_scope(Scope* script_scope) { script_scope_ = script_scope; } | |
152 | |
153 AstValueFactory* ast_value_factory() { return ast_value_factory_; } | |
154 void set_ast_value_factory(AstValueFactory* ast_value_factory) { | |
155 ast_value_factory_ = ast_value_factory; | |
156 } | |
157 | |
158 FunctionLiteral* function() { // TODO(titzer): temporary name adapter | |
159 return literal_; | |
160 } | |
161 FunctionLiteral* literal() { return literal_; } | |
162 void set_literal(FunctionLiteral* literal) { literal_ = literal; } | |
163 | |
164 Scope* scope() { return scope_; } | |
165 void set_scope(Scope* scope) { scope_ = scope; } | |
166 | |
167 UnicodeCache* unicode_cache() { return unicode_cache_; } | |
168 void set_unicode_cache(UnicodeCache* unicode_cache) { | |
169 unicode_cache_ = unicode_cache; | |
170 } | |
171 | |
172 uintptr_t stack_limit() { return stack_limit_; } | |
173 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } | |
174 | |
175 uint32_t hash_seed() { return hash_seed_; } | |
176 void set_hash_seed(uint32_t hash_seed) { hash_seed_ = hash_seed; } | |
177 | |
178 //-------------------------------------------------------------------------- | |
179 // TODO(titzer): these should not be part of ParseInfo. | |
180 //-------------------------------------------------------------------------- | |
181 Isolate* isolate() { return isolate_; } | |
182 Handle<JSFunction> closure() { return closure_; } | |
183 Handle<SharedFunctionInfo> shared_info() { return shared_; } | |
184 Handle<Script> script() { return script_; } | |
185 Handle<Context> context() { return context_; } | |
186 void clear_script() { script_ = Handle<Script>::null(); } | |
187 void set_context(Handle<Context> context) { context_ = context; } | |
188 void set_script(Handle<Script> script) { script_ = script; } | |
189 //-------------------------------------------------------------------------- | |
190 | |
191 LanguageMode language_mode() { | |
192 return construct_language_mode(is_strict_mode(), is_strong_mode()); | |
193 } | |
194 void set_language_mode(LanguageMode language_mode) { | |
195 STATIC_ASSERT(LANGUAGE_END == 3); | |
196 set_strict_mode(language_mode & STRICT_BIT); | |
197 set_strong_mode(language_mode & STRONG_BIT); | |
198 } | |
199 | |
200 void DeleteAstValueFactory() { | |
201 if (ast_value_factory_owned()) { | |
202 delete ast_value_factory_; | |
203 set_ast_value_factory_owned(false); | |
204 } | |
205 ast_value_factory_ = nullptr; | |
206 } | |
207 | |
208 void ReopenHandlesInNewHandleScope() { | |
209 closure_ = Handle<JSFunction>(*closure_); | |
210 shared_ = Handle<SharedFunctionInfo>(*shared_); | |
211 script_ = Handle<Script>(*script_); | |
212 context_ = Handle<Context>(*context_); | |
213 } | |
214 | |
215 private: | |
216 //------------- Inputs to parsing and scope analysis ----------------------- | |
rossberg
2015/03/04 10:25:12
Nit: Would be even more useful to have these secti
| |
217 Zone* zone_; | |
218 unsigned flags_; | |
219 ScriptCompiler::ExternalSourceStream* source_stream_; | |
220 ScriptCompiler::StreamedSource::Encoding source_stream_encoding_; | |
221 v8::Extension* extension_; | |
222 ScriptCompiler::CompileOptions compile_options_; | |
223 Scope* script_scope_; | |
224 UnicodeCache* unicode_cache_; | |
225 uintptr_t stack_limit_; | |
226 uint32_t hash_seed_; | |
227 | |
228 // TODO(titzer): these should *not* be part of ParseInfo. Refactor Parser. | |
marja
2015/03/04 09:24:40
Yes! :)
titzer
2015/03/05 20:18:30
I'm not sure exactly where these will land, but I
| |
229 Isolate* isolate_; | |
230 Handle<JSFunction> closure_; | |
231 Handle<SharedFunctionInfo> shared_; | |
232 Handle<Script> script_; | |
233 Handle<Context> context_; | |
234 | |
235 //----------- Inputs+Outputs of parsing and scope analysis ----------------- | |
236 ScriptData** cached_data_; // used if available, populated if requested. | |
237 AstValueFactory* ast_value_factory_; // used if available, otherwise new. | |
238 | |
239 //----------- Outputs of parsing and scope analysis ------------------------ | |
240 FunctionLiteral* literal_; // produced by full parser. | |
241 Scope* scope_; // produced by scope analysis. | |
242 | |
243 void SetFlag(Flag f) { flags_ |= f; } | |
244 void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; } | |
245 bool GetFlag(Flag f) const { return (flags_ & f) != 0; } | |
246 | |
247 void set_shared_info(Handle<SharedFunctionInfo> shared) { shared_ = shared; } | |
248 void set_closure(Handle<JSFunction> closure) { closure_ = closure; } | |
249 }; | |
27 | 250 |
28 class FunctionEntry BASE_EMBEDDED { | 251 class FunctionEntry BASE_EMBEDDED { |
29 public: | 252 public: |
30 enum { | 253 enum { |
31 kStartPositionIndex, | 254 kStartPositionIndex, |
32 kEndPositionIndex, | 255 kEndPositionIndex, |
33 kLiteralCountIndex, | 256 kLiteralCountIndex, |
34 kPropertyCountIndex, | 257 kPropertyCountIndex, |
35 kLanguageModeIndex, | 258 kLanguageModeIndex, |
36 kUsesSuperPropertyIndex, | 259 kUsesSuperPropertyIndex, |
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
629 return tag != NULL; | 852 return tag != NULL; |
630 } | 853 } |
631 | 854 |
632 private: | 855 private: |
633 Parser* parser_; | 856 Parser* parser_; |
634 }; | 857 }; |
635 | 858 |
636 | 859 |
637 class Parser : public ParserBase<ParserTraits> { | 860 class Parser : public ParserBase<ParserTraits> { |
638 public: | 861 public: |
639 Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed, | 862 explicit Parser(ParseInfo* info); |
640 UnicodeCache* unicode_cache); | |
641 ~Parser() { | 863 ~Parser() { |
642 delete reusable_preparser_; | 864 delete reusable_preparser_; |
643 reusable_preparser_ = NULL; | 865 reusable_preparser_ = NULL; |
644 delete cached_parse_data_; | 866 delete cached_parse_data_; |
645 cached_parse_data_ = NULL; | 867 cached_parse_data_ = NULL; |
646 } | 868 } |
647 | 869 |
648 // Parses the source code represented by the compilation info and sets its | 870 // Parses the source code represented by the compilation info and sets its |
649 // function literal. Returns false (and deallocates any allocated AST | 871 // function literal. Returns false (and deallocates any allocated AST |
650 // nodes) if parsing failed. | 872 // nodes) if parsing failed. |
651 static bool ParseStatic(CompilationInfo* info, bool allow_lazy = false); | 873 static bool ParseStatic(ParseInfo* info, bool allow_lazy = false); |
652 bool Parse(CompilationInfo* info); | 874 bool Parse(ParseInfo* info); |
653 void ParseOnBackground(CompilationInfo* info); | 875 void ParseOnBackground(ParseInfo* info); |
654 | 876 |
655 // Handle errors detected during parsing, move statistics to Isolate, | 877 // Handle errors detected during parsing, move statistics to Isolate, |
656 // internalize strings (move them to the heap). | 878 // internalize strings (move them to the heap). |
657 void Internalize(Isolate* isolate, Handle<Script> script, bool error); | 879 void Internalize(Isolate* isolate, Handle<Script> script, bool error); |
658 void HandleSourceURLComments(Isolate* isolate, Handle<Script> script); | 880 void HandleSourceURLComments(Isolate* isolate, Handle<Script> script); |
659 | 881 |
660 private: | 882 private: |
661 friend class ParserTraits; | 883 friend class ParserTraits; |
662 | 884 |
663 // Limit the allowed number of local variables in a function. The hard limit | 885 // Limit the allowed number of local variables in a function. The hard limit |
664 // is that offsets computed by FullCodeGenerator::StackOperand and similar | 886 // is that offsets computed by FullCodeGenerator::StackOperand and similar |
665 // functions are ints, and they should not overflow. In addition, accessing | 887 // functions are ints, and they should not overflow. In addition, accessing |
666 // local variables creates user-controlled constants in the generated code, | 888 // local variables creates user-controlled constants in the generated code, |
667 // and we don't want too much user-controlled memory inside the code (this was | 889 // and we don't want too much user-controlled memory inside the code (this was |
668 // the reason why this limit was introduced in the first place; see | 890 // the reason why this limit was introduced in the first place; see |
669 // https://codereview.chromium.org/7003030/ ). | 891 // https://codereview.chromium.org/7003030/ ). |
670 static const int kMaxNumFunctionLocals = 4194303; // 2^22-1 | 892 static const int kMaxNumFunctionLocals = 4194303; // 2^22-1 |
671 | 893 |
672 // Returns NULL if parsing failed. | 894 // Returns NULL if parsing failed. |
673 FunctionLiteral* ParseProgram(Isolate* isolate, CompilationInfo* info); | 895 FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info); |
674 | 896 |
675 FunctionLiteral* ParseLazy(Isolate* isolate, CompilationInfo* info); | 897 FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info); |
676 FunctionLiteral* ParseLazy(Isolate* isolate, CompilationInfo* info, | 898 FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info, |
677 Utf16CharacterStream* source); | 899 Utf16CharacterStream* source); |
678 | 900 |
679 // Called by ParseProgram after setting up the scanner. | 901 // Called by ParseProgram after setting up the scanner. |
680 FunctionLiteral* DoParseProgram(CompilationInfo* info, Scope** scope, | 902 FunctionLiteral* DoParseProgram(ParseInfo* info, Scope** scope, |
681 Scope** ad_hoc_eval_scope); | 903 Scope** ad_hoc_eval_scope); |
682 | 904 |
683 void SetCachedData(CompilationInfo* info); | 905 void SetCachedData(ParseInfo* info); |
684 | 906 |
685 bool inside_with() const { return scope_->inside_with(); } | 907 bool inside_with() const { return scope_->inside_with(); } |
686 ScriptCompiler::CompileOptions compile_options() const { | 908 ScriptCompiler::CompileOptions compile_options() const { |
687 return compile_options_; | 909 return compile_options_; |
688 } | 910 } |
689 bool consume_cached_parse_data() const { | 911 bool consume_cached_parse_data() const { |
690 return compile_options_ == ScriptCompiler::kConsumeParserCache && | 912 return compile_options_ == ScriptCompiler::kConsumeParserCache && |
691 cached_parse_data_ != NULL; | 913 cached_parse_data_ != NULL; |
692 } | 914 } |
693 bool produce_cached_parse_data() const { | 915 bool produce_cached_parse_data() const { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 } | 1163 } |
942 | 1164 |
943 | 1165 |
944 Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state, | 1166 Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state, |
945 int start, Expression* tag) { | 1167 int start, Expression* tag) { |
946 return parser_->CloseTemplateLiteral(state, start, tag); | 1168 return parser_->CloseTemplateLiteral(state, start, tag); |
947 } | 1169 } |
948 } } // namespace v8::internal | 1170 } } // namespace v8::internal |
949 | 1171 |
950 #endif // V8_PARSER_H_ | 1172 #endif // V8_PARSER_H_ |
OLD | NEW |