Chromium Code Reviews| 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 |