Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: src/parser.cc

Issue 3518005: Make some free functions into static members of class Parser. (Closed)
Patch Set: Remove outdated comment. Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 29 matching lines...) Expand all
40 #include "scopeinfo.h" 40 #include "scopeinfo.h"
41 #include "scopes.h" 41 #include "scopes.h"
42 #include "string-stream.h" 42 #include "string-stream.h"
43 43
44 #include "ast-inl.h" 44 #include "ast-inl.h"
45 #include "jump-target-inl.h" 45 #include "jump-target-inl.h"
46 46
47 namespace v8 { 47 namespace v8 {
48 namespace internal { 48 namespace internal {
49 49
50 class ParserFactory;
51 class ParserLog;
52 class TemporaryScope;
53 class Target;
54
55 template <typename T> class ZoneListWrapper;
56
57
58 // PositionStack is used for on-stack allocation of token positions for 50 // PositionStack is used for on-stack allocation of token positions for
59 // new expressions. Please look at ParseNewExpression. 51 // new expressions. Please look at ParseNewExpression.
60 52
61 class PositionStack { 53 class PositionStack {
62 public: 54 public:
63 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {} 55 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {}
64 ~PositionStack() { ASSERT(!*ok_ || is_empty()); } 56 ~PositionStack() { ASSERT(!*ok_ || is_empty()); }
65 57
66 class Element { 58 class Element {
67 public: 59 public:
(...skipping 20 matching lines...) Expand all
88 } 80 }
89 81
90 private: 82 private:
91 Element* top() { return top_; } 83 Element* top() { return top_; }
92 void set_top(Element* value) { top_ = value; } 84 void set_top(Element* value) { top_ = value; }
93 Element* top_; 85 Element* top_;
94 bool* ok_; 86 bool* ok_;
95 }; 87 };
96 88
97 89
98 class Parser {
99 public:
100 Parser(Handle<Script> script, bool allow_natives_syntax,
101 v8::Extension* extension, ParserMode is_pre_parsing,
102 ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data);
103 virtual ~Parser() { }
104
105 // Pre-parse the program from the character stream; returns true on
106 // success, false if a stack-overflow happened during parsing.
107 bool PreParseProgram(Handle<String> source, unibrow::CharacterStream* stream);
108
109 void ReportMessage(const char* message, Vector<const char*> args);
110 virtual void ReportMessageAt(Scanner::Location loc,
111 const char* message,
112 Vector<const char*> args) = 0;
113
114
115 // Returns NULL if parsing failed.
116 FunctionLiteral* ParseProgram(Handle<String> source,
117 bool in_global_context);
118 FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info);
119 FunctionLiteral* ParseJson(Handle<String> source);
120
121 // The minimum number of contiguous assignment that will
122 // be treated as an initialization block. Benchmarks show that
123 // the overhead exceeds the savings below this limit.
124 static const int kMinInitializationBlock = 3;
125
126 protected:
127
128 enum Mode {
129 PARSE_LAZILY,
130 PARSE_EAGERLY
131 };
132
133 // Report syntax error
134 void ReportUnexpectedToken(Token::Value token);
135 void ReportInvalidPreparseData(Handle<String> name, bool* ok);
136
137 Handle<Script> script_;
138 Scanner scanner_;
139
140 Scope* top_scope_;
141 int with_nesting_level_;
142
143 TemporaryScope* temp_scope_;
144 Mode mode_;
145
146 Target* target_stack_; // for break, continue statements
147 bool allow_natives_syntax_;
148 v8::Extension* extension_;
149 ParserFactory* factory_;
150 ParserLog* log_;
151 bool is_pre_parsing_;
152 ScriptDataImpl* pre_data_;
153 FuncNameInferrer* fni_;
154
155 bool inside_with() const { return with_nesting_level_ > 0; }
156 ParserFactory* factory() const { return factory_; }
157 ParserLog* log() const { return log_; }
158 Scanner& scanner() { return scanner_; }
159 Mode mode() const { return mode_; }
160 ScriptDataImpl* pre_data() const { return pre_data_; }
161
162 // All ParseXXX functions take as the last argument an *ok parameter
163 // which is set to false if parsing failed; it is unchanged otherwise.
164 // By making the 'exception handling' explicit, we are forced to check
165 // for failure at the call sites.
166 void* ParseSourceElements(ZoneListWrapper<Statement>* processor,
167 int end_token, bool* ok);
168 Statement* ParseStatement(ZoneStringList* labels, bool* ok);
169 Statement* ParseFunctionDeclaration(bool* ok);
170 Statement* ParseNativeDeclaration(bool* ok);
171 Block* ParseBlock(ZoneStringList* labels, bool* ok);
172 Block* ParseVariableStatement(bool* ok);
173 Block* ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok);
174 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
175 bool* ok);
176 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
177 Statement* ParseContinueStatement(bool* ok);
178 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
179 Statement* ParseReturnStatement(bool* ok);
180 Block* WithHelper(Expression* obj,
181 ZoneStringList* labels,
182 bool is_catch_block,
183 bool* ok);
184 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
185 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
186 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
187 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
188 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
189 Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
190 Statement* ParseThrowStatement(bool* ok);
191 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
192 TryStatement* ParseTryStatement(bool* ok);
193 DebuggerStatement* ParseDebuggerStatement(bool* ok);
194
195 Expression* ParseExpression(bool accept_IN, bool* ok);
196 Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
197 Expression* ParseConditionalExpression(bool accept_IN, bool* ok);
198 Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
199 Expression* ParseUnaryExpression(bool* ok);
200 Expression* ParsePostfixExpression(bool* ok);
201 Expression* ParseLeftHandSideExpression(bool* ok);
202 Expression* ParseNewExpression(bool* ok);
203 Expression* ParseMemberExpression(bool* ok);
204 Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
205 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
206 bool* ok);
207 Expression* ParsePrimaryExpression(bool* ok);
208 Expression* ParseArrayLiteral(bool* ok);
209 Expression* ParseObjectLiteral(bool* ok);
210 ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
211 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
212
213 Expression* NewCompareNode(Token::Value op,
214 Expression* x,
215 Expression* y,
216 int position);
217
218 // Populate the constant properties fixed array for a materialized object
219 // literal.
220 void BuildObjectLiteralConstantProperties(
221 ZoneList<ObjectLiteral::Property*>* properties,
222 Handle<FixedArray> constants,
223 bool* is_simple,
224 bool* fast_elements,
225 int* depth);
226
227 // Populate the literals fixed array for a materialized array literal.
228 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
229 Handle<FixedArray> constants,
230 bool* is_simple,
231 int* depth);
232
233 // Decide if a property should be in the object boilerplate.
234 bool IsBoilerplateProperty(ObjectLiteral::Property* property);
235 // If the expression is a literal, return the literal value;
236 // if the expression is a materialized literal and is simple return a
237 // compile time value as encoded by CompileTimeValue::GetValue().
238 // Otherwise, return undefined literal as the placeholder
239 // in the object literal boilerplate.
240 Handle<Object> GetBoilerplateValue(Expression* expression);
241
242 enum FunctionLiteralType {
243 EXPRESSION,
244 DECLARATION,
245 NESTED
246 };
247
248 ZoneList<Expression*>* ParseArguments(bool* ok);
249 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
250 int function_token_position,
251 FunctionLiteralType type,
252 bool* ok);
253
254
255 // Magical syntax support.
256 Expression* ParseV8Intrinsic(bool* ok);
257
258 INLINE(Token::Value peek()) { return scanner_.peek(); }
259 INLINE(Token::Value Next()) { return scanner_.Next(); }
260 INLINE(void Consume(Token::Value token));
261 void Expect(Token::Value token, bool* ok);
262 bool Check(Token::Value token);
263 void ExpectSemicolon(bool* ok);
264
265 Handle<String> GetSymbol(bool* ok);
266
267 // Get odd-ball literals.
268 Literal* GetLiteralUndefined();
269 Literal* GetLiteralTheHole();
270 Literal* GetLiteralNumber(double value);
271
272 Handle<String> ParseIdentifier(bool* ok);
273 Handle<String> ParseIdentifierName(bool* ok);
274 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
275 bool* is_set,
276 bool* ok);
277
278 // Parser support
279 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
280 FunctionLiteral* fun,
281 bool resolve,
282 bool* ok) = 0;
283
284 bool TargetStackContainsLabel(Handle<String> label);
285 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
286 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
287
288 void RegisterTargetUse(BreakTarget* target, Target* stop);
289
290 // Create a number literal.
291 Literal* NewNumberLiteral(double value);
292
293 // Generate AST node that throw a ReferenceError with the given type.
294 Expression* NewThrowReferenceError(Handle<String> type);
295
296 // Generate AST node that throw a SyntaxError with the given
297 // type. The first argument may be null (in the handle sense) in
298 // which case no arguments are passed to the constructor.
299 Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
300
301 // Generate AST node that throw a TypeError with the given
302 // type. Both arguments must be non-null (in the handle sense).
303 Expression* NewThrowTypeError(Handle<String> type,
304 Handle<Object> first,
305 Handle<Object> second);
306
307 // Generic AST generator for throwing errors from compiled code.
308 Expression* NewThrowError(Handle<String> constructor,
309 Handle<String> type,
310 Vector< Handle<Object> > arguments);
311
312 // JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
313 // specification section 15.12.1 (and appendix A.8).
314 // The grammar is given section 15.12.1.2 (and appendix A.8.2).
315
316 // Parse JSON input as a single JSON value.
317 Expression* ParseJson(bool* ok);
318
319 // Parse a single JSON value from input (grammar production JSONValue).
320 // A JSON value is either a (double-quoted) string literal, a number literal,
321 // one of "true", "false", or "null", or an object or array literal.
322 Expression* ParseJsonValue(bool* ok);
323 // Parse a JSON object literal (grammar production JSONObject).
324 // An object literal is a squiggly-braced and comma separated sequence
325 // (possibly empty) of key/value pairs, where the key is a JSON string
326 // literal, the value is a JSON value, and the two are spearated by a colon.
327 // A JavaScript object also allows numbers and identifiers as keys.
328 Expression* ParseJsonObject(bool* ok);
329 // Parses a JSON array literal (grammar production JSONArray). An array
330 // literal is a square-bracketed and comma separated sequence (possibly empty)
331 // of JSON values.
332 // A JavaScript array allows leaving out values from the sequence.
333 Expression* ParseJsonArray(bool* ok);
334
335 friend class Target;
336 friend class TargetScope;
337 friend class LexicalScope;
338 friend class TemporaryScope;
339 };
340
341
342 template <typename T, int initial_size> 90 template <typename T, int initial_size>
343 class BufferedZoneList { 91 class BufferedZoneList {
344 public: 92 public:
345 BufferedZoneList() : list_(NULL), last_(NULL) {} 93 BufferedZoneList() : list_(NULL), last_(NULL) {}
346 94
347 // Adds element at end of list. This element is buffered and can 95 // Adds element at end of list. This element is buffered and can
348 // be read using last() or removed using RemoveLast until a new Add or until 96 // be read using last() or removed using RemoveLast until a new Add or until
349 // RemoveLast or GetList has been called. 97 // RemoveLast or GetList has been called.
350 void Add(T* value) { 98 void Add(T* value) {
351 if (last_ != NULL) { 99 if (last_ != NULL) {
(...skipping 5142 matching lines...) Expand 10 before | Expand all | Expand 10 after
5494 } 5242 }
5495 5243
5496 5244
5497 bool ScriptDataImpl::HasError() { 5245 bool ScriptDataImpl::HasError() {
5498 return has_error(); 5246 return has_error();
5499 } 5247 }
5500 5248
5501 5249
5502 // Preparse, but only collect data that is immediately useful, 5250 // Preparse, but only collect data that is immediately useful,
5503 // even if the preparser data is only used once. 5251 // even if the preparser data is only used once.
5504 ScriptDataImpl* PartialPreParse(Handle<String> source, 5252 ScriptDataImpl* Parser::PartialPreParse(Handle<String> source,
5505 unibrow::CharacterStream* stream, 5253 unibrow::CharacterStream* stream,
5506 v8::Extension* extension) { 5254 v8::Extension* extension) {
5507 Handle<Script> no_script; 5255 Handle<Script> no_script;
5508 bool allow_natives_syntax = 5256 bool allow_natives_syntax =
5509 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); 5257 FLAG_allow_natives_syntax || Bootstrapper::IsActive();
5510 PartialPreParser parser(no_script, allow_natives_syntax, extension); 5258 PartialPreParser parser(no_script, allow_natives_syntax, extension);
5511 if (!parser.PreParseProgram(source, stream)) return NULL; 5259 if (!parser.PreParseProgram(source, stream)) return NULL;
5512 // Extract the accumulated data from the recorder as a single 5260 // Extract the accumulated data from the recorder as a single
5513 // contiguous vector that we are responsible for disposing. 5261 // contiguous vector that we are responsible for disposing.
5514 Vector<unsigned> store = parser.recorder()->ExtractData(); 5262 Vector<unsigned> store = parser.recorder()->ExtractData();
5515 return new ScriptDataImpl(store); 5263 return new ScriptDataImpl(store);
5516 } 5264 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5552 if (data >= symbol_data_end_) return -1; 5300 if (data >= symbol_data_end_) return -1;
5553 input = *data; 5301 input = *data;
5554 result = (result << 7) | (input & 0x7f); 5302 result = (result << 7) | (input & 0x7f);
5555 data++; 5303 data++;
5556 } 5304 }
5557 *source = data; 5305 *source = data;
5558 return result; 5306 return result;
5559 } 5307 }
5560 5308
5561 5309
5562 ScriptDataImpl* PreParse(Handle<String> source, 5310 ScriptDataImpl* Parser::PreParse(Handle<String> source,
5563 unibrow::CharacterStream* stream, 5311 unibrow::CharacterStream* stream,
5564 v8::Extension* extension) { 5312 v8::Extension* extension) {
5565 Handle<Script> no_script; 5313 Handle<Script> no_script;
5566 bool allow_natives_syntax = 5314 bool allow_natives_syntax =
5567 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); 5315 FLAG_allow_natives_syntax || Bootstrapper::IsActive();
5568 CompletePreParser parser(no_script, allow_natives_syntax, extension); 5316 CompletePreParser parser(no_script, allow_natives_syntax, extension);
5569 if (!parser.PreParseProgram(source, stream)) return NULL; 5317 if (!parser.PreParseProgram(source, stream)) return NULL;
5570 // Extract the accumulated data from the recorder as a single 5318 // Extract the accumulated data from the recorder as a single
5571 // contiguous vector that we are responsible for disposing. 5319 // contiguous vector that we are responsible for disposing.
5572 Vector<unsigned> store = parser.recorder()->ExtractData(); 5320 Vector<unsigned> store = parser.recorder()->ExtractData();
5573 return new ScriptDataImpl(store); 5321 return new ScriptDataImpl(store);
5574 } 5322 }
5575 5323
5576 5324
5577 bool ParseRegExp(FlatStringReader* input, 5325 bool Parser::ParseRegExp(FlatStringReader* input,
5578 bool multiline, 5326 bool multiline,
5579 RegExpCompileData* result) { 5327 RegExpCompileData* result) {
5580 ASSERT(result != NULL); 5328 ASSERT(result != NULL);
5581 RegExpParser parser(input, &result->error, multiline); 5329 RegExpParser parser(input, &result->error, multiline);
5582 RegExpTree* tree = parser.ParsePattern(); 5330 RegExpTree* tree = parser.ParsePattern();
5583 if (parser.failed()) { 5331 if (parser.failed()) {
5584 ASSERT(tree == NULL); 5332 ASSERT(tree == NULL);
5585 ASSERT(!result->error.is_null()); 5333 ASSERT(!result->error.is_null());
5586 } else { 5334 } else {
5587 ASSERT(tree != NULL); 5335 ASSERT(tree != NULL);
5588 ASSERT(result->error.is_null()); 5336 ASSERT(result->error.is_null());
5589 result->tree = tree; 5337 result->tree = tree;
5590 int capture_count = parser.captures_started(); 5338 int capture_count = parser.captures_started();
5591 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 5339 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
5592 result->contains_anchor = parser.contains_anchor(); 5340 result->contains_anchor = parser.contains_anchor();
5593 result->capture_count = capture_count; 5341 result->capture_count = capture_count;
5594 } 5342 }
5595 return !parser.failed(); 5343 return !parser.failed();
5596 } 5344 }
5597 5345
5598 5346
5599 // MakeAST is just a wrapper for the corresponding Parser calls so we don't 5347 FunctionLiteral* Parser::MakeAST(bool compile_in_global_context,
5600 // have to expose the entire Parser class in the .h file. 5348 Handle<Script> script,
5601 FunctionLiteral* MakeAST(bool compile_in_global_context, 5349 v8::Extension* extension,
5602 Handle<Script> script, 5350 ScriptDataImpl* pre_data,
5603 v8::Extension* extension, 5351 bool is_json) {
5604 ScriptDataImpl* pre_data,
5605 bool is_json) {
5606 bool allow_natives_syntax = 5352 bool allow_natives_syntax =
5607 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); 5353 FLAG_allow_natives_syntax || Bootstrapper::IsActive();
5608 AstBuildingParser parser(script, allow_natives_syntax, extension, pre_data); 5354 AstBuildingParser parser(script, allow_natives_syntax, extension, pre_data);
5609 if (pre_data != NULL && pre_data->has_error()) { 5355 if (pre_data != NULL && pre_data->has_error()) {
5610 Scanner::Location loc = pre_data->MessageLocation(); 5356 Scanner::Location loc = pre_data->MessageLocation();
5611 const char* message = pre_data->BuildMessage(); 5357 const char* message = pre_data->BuildMessage();
5612 Vector<const char*> args = pre_data->BuildArgs(); 5358 Vector<const char*> args = pre_data->BuildArgs();
5613 parser.ReportMessageAt(loc, message, args); 5359 parser.ReportMessageAt(loc, message, args);
5614 DeleteArray(message); 5360 DeleteArray(message);
5615 for (int i = 0; i < args.length(); i++) { 5361 for (int i = 0; i < args.length(); i++) {
5616 DeleteArray(args[i]); 5362 DeleteArray(args[i]);
5617 } 5363 }
5618 DeleteArray(args.start()); 5364 DeleteArray(args.start());
5619 return NULL; 5365 return NULL;
5620 } 5366 }
5621 Handle<String> source = Handle<String>(String::cast(script->source())); 5367 Handle<String> source = Handle<String>(String::cast(script->source()));
5622 FunctionLiteral* result; 5368 FunctionLiteral* result;
5623 if (is_json) { 5369 if (is_json) {
5624 ASSERT(compile_in_global_context); 5370 ASSERT(compile_in_global_context);
5625 result = parser.ParseJson(source); 5371 result = parser.ParseJson(source);
5626 } else { 5372 } else {
5627 result = parser.ParseProgram(source, compile_in_global_context); 5373 result = parser.ParseProgram(source, compile_in_global_context);
5628 } 5374 }
5629 return result; 5375 return result;
5630 } 5376 }
5631 5377
5632 5378
5633 FunctionLiteral* MakeLazyAST(Handle<SharedFunctionInfo> info) { 5379 FunctionLiteral* Parser::MakeLazyAST(Handle<SharedFunctionInfo> info) {
5634 Handle<Script> script(Script::cast(info->script())); 5380 Handle<Script> script(Script::cast(info->script()));
5635 AstBuildingParser parser(script, true, NULL, NULL); 5381 AstBuildingParser parser(script, true, NULL, NULL);
5636 FunctionLiteral* result = parser.ParseLazy(info); 5382 FunctionLiteral* result = parser.ParseLazy(info);
5637 return result; 5383 return result;
5638 } 5384 }
5639 5385
5640 #undef NEW 5386 #undef NEW
5641 5387
5642 } } // namespace v8::internal 5388 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698