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

Side by Side Diff: src/parser.cc

Issue 549207: Added validating JSON parser mode to parser. (Closed)
Patch Set: Created 10 years, 10 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
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 Element* top() { return top_; } 84 Element* top() { return top_; }
85 void set_top(Element* value) { top_ = value; } 85 void set_top(Element* value) { top_ = value; }
86 Element* top_; 86 Element* top_;
87 bool* ok_; 87 bool* ok_;
88 }; 88 };
89 89
90 90
91 class Parser { 91 class Parser {
92 public: 92 public:
93 Parser(Handle<Script> script, bool allow_natives_syntax, 93 Parser(Handle<Script> script, bool allow_natives_syntax,
94 v8::Extension* extension, bool is_pre_parsing, 94 v8::Extension* extension, ParserMode is_pre_parsing,
95 ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data); 95 ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data);
96 virtual ~Parser() { } 96 virtual ~Parser() { }
97 97
98 // Pre-parse the program from the character stream; returns true on 98 // Pre-parse the program from the character stream; returns true on
99 // success, false if a stack-overflow happened during parsing. 99 // success, false if a stack-overflow happened during parsing.
100 bool PreParseProgram(Handle<String> source, unibrow::CharacterStream* stream); 100 bool PreParseProgram(Handle<String> source, unibrow::CharacterStream* stream);
101 101
102 void ReportMessage(const char* message, Vector<const char*> args); 102 void ReportMessage(const char* message, Vector<const char*> args);
103 virtual void ReportMessageAt(Scanner::Location loc, 103 virtual void ReportMessageAt(Scanner::Location loc,
104 const char* message, 104 const char* message,
105 Vector<const char*> args) = 0; 105 Vector<const char*> args) = 0;
106 106
107 107
108 // Returns NULL if parsing failed. 108 // Returns NULL if parsing failed.
109 FunctionLiteral* ParseProgram(Handle<String> source, 109 FunctionLiteral* ParseProgram(Handle<String> source,
110 unibrow::CharacterStream* stream, 110 unibrow::CharacterStream* stream,
111 bool in_global_context); 111 bool in_global_context);
112 FunctionLiteral* ParseLazy(Handle<String> source, 112 FunctionLiteral* ParseLazy(Handle<String> source,
113 Handle<String> name, 113 Handle<String> name,
114 int start_position, bool is_expression); 114 int start_position, bool is_expression);
115 FunctionLiteral* ParseJson(Handle<String> source,
116 unibrow::CharacterStream* stream);
115 117
116 // The minimum number of contiguous assignment that will 118 // The minimum number of contiguous assignment that will
117 // be treated as an initialization block. Benchmarks show that 119 // be treated as an initialization block. Benchmarks show that
118 // the overhead exceeds the savings below this limit. 120 // the overhead exceeds the savings below this limit.
119 static const int kMinInitializationBlock = 3; 121 static const int kMinInitializationBlock = 3;
120 122
121 protected: 123 protected:
122 124
123 enum Mode { 125 enum Mode {
124 PARSE_LAZILY, 126 PARSE_LAZILY,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 Expression* ParseNewExpression(bool* ok); 197 Expression* ParseNewExpression(bool* ok);
196 Expression* ParseMemberExpression(bool* ok); 198 Expression* ParseMemberExpression(bool* ok);
197 Expression* ParseNewPrefix(PositionStack* stack, bool* ok); 199 Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
198 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack, 200 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
199 bool* ok); 201 bool* ok);
200 Expression* ParsePrimaryExpression(bool* ok); 202 Expression* ParsePrimaryExpression(bool* ok);
201 Expression* ParseArrayLiteral(bool* ok); 203 Expression* ParseArrayLiteral(bool* ok);
202 Expression* ParseObjectLiteral(bool* ok); 204 Expression* ParseObjectLiteral(bool* ok);
203 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); 205 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
204 206
205 // Decide if a property should be the object boilerplate. 207 // Populate the constant properties fixed array for a materialized object
208 // literal.
209 void BuildObjectLiteralConstantProperties(
210 ZoneList<ObjectLiteral::Property*>* properties,
211 Handle<FixedArray> constants,
212 bool* is_simple_out,
Mads Ager (chromium) 2010/02/01 08:42:19 Remove the _out prefix on these out params?
Lasse Reichstein 2010/02/01 12:17:30 Done.
213 int* depth_out);
214
215 // Populate the literals fixed array for a materialized array literal.
216 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
217 Handle<FixedArray> constants,
218 bool* is_simple_out,
Mads Ager (chromium) 2010/02/01 08:42:19 Remove _out on these as well?
Lasse Reichstein 2010/02/01 12:17:30 Done, too.
219 int* depth_out);
220
221 // Decide if a property should be in the object boilerplate.
206 bool IsBoilerplateProperty(ObjectLiteral::Property* property); 222 bool IsBoilerplateProperty(ObjectLiteral::Property* property);
207 // If the expression is a literal, return the literal value; 223 // If the expression is a literal, return the literal value;
208 // if the expression is a materialized literal and is simple return a 224 // if the expression is a materialized literal and is simple return a
209 // compile time value as encoded by CompileTimeValue::GetValue(). 225 // compile time value as encoded by CompileTimeValue::GetValue().
210 // Otherwise, return undefined literal as the placeholder 226 // Otherwise, return undefined literal as the placeholder
211 // in the object literal boilerplate. 227 // in the object literal boilerplate.
212 Handle<Object> GetBoilerplateValue(Expression* expression); 228 Handle<Object> GetBoilerplateValue(Expression* expression);
213 229
214 enum FunctionLiteralType { 230 enum FunctionLiteralType {
215 EXPRESSION, 231 EXPRESSION,
216 DECLARATION, 232 DECLARATION,
217 NESTED 233 NESTED
218 }; 234 };
219 235
220 ZoneList<Expression*>* ParseArguments(bool* ok); 236 ZoneList<Expression*>* ParseArguments(bool* ok);
221 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name, 237 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
222 int function_token_position, 238 int function_token_position,
223 FunctionLiteralType type, 239 FunctionLiteralType type,
224 bool* ok); 240 bool* ok);
225 241
226 242
227 // Magical syntax support. 243 // Magical syntax support.
228 Expression* ParseV8Intrinsic(bool* ok); 244 Expression* ParseV8Intrinsic(bool* ok);
229 245
230 INLINE(Token::Value peek()) { return scanner_.peek(); } 246 INLINE(Token::Value peek()) { return scanner_.peek(); }
231 INLINE(Token::Value Next()) { return scanner_.Next(); } 247 INLINE(Token::Value Next()) { return scanner_.Next(); }
232 INLINE(void Consume(Token::Value token)); 248 INLINE(void Consume(Token::Value token));
233 void Expect(Token::Value token, bool* ok); 249 void Expect(Token::Value token, bool* ok);
250 bool Check(Token::Value token);
234 void ExpectSemicolon(bool* ok); 251 void ExpectSemicolon(bool* ok);
235 252
236 // Get odd-ball literals. 253 // Get odd-ball literals.
237 Literal* GetLiteralUndefined(); 254 Literal* GetLiteralUndefined();
238 Literal* GetLiteralTheHole(); 255 Literal* GetLiteralTheHole();
239 Literal* GetLiteralNumber(double value); 256 Literal* GetLiteralNumber(double value);
240 257
241 Handle<String> ParseIdentifier(bool* ok); 258 Handle<String> ParseIdentifier(bool* ok);
242 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, 259 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
243 bool* is_set, 260 bool* is_set,
(...skipping 26 matching lines...) Expand all
270 // type. Both arguments must be non-null (in the handle sense). 287 // type. Both arguments must be non-null (in the handle sense).
271 Expression* NewThrowTypeError(Handle<String> type, 288 Expression* NewThrowTypeError(Handle<String> type,
272 Handle<Object> first, 289 Handle<Object> first,
273 Handle<Object> second); 290 Handle<Object> second);
274 291
275 // Generic AST generator for throwing errors from compiled code. 292 // Generic AST generator for throwing errors from compiled code.
276 Expression* NewThrowError(Handle<String> constructor, 293 Expression* NewThrowError(Handle<String> constructor,
277 Handle<String> type, 294 Handle<String> type,
278 Vector< Handle<Object> > arguments); 295 Vector< Handle<Object> > arguments);
279 296
297 // Parse JSON expressions and sub-expressions.
298 Expression* ParseJson(bool* ok);
299 Expression* ParseJsonValue(bool* ok);
300 Expression* ParseJsonObject(bool* ok);
301 Expression* ParseJsonArray(bool* ok);
302
280 friend class Target; 303 friend class Target;
281 friend class TargetScope; 304 friend class TargetScope;
282 friend class LexicalScope; 305 friend class LexicalScope;
283 friend class TemporaryScope; 306 friend class TemporaryScope;
284 }; 307 };
285 308
286 309
287 template <typename T, int initial_size> 310 template <typename T, int initial_size>
288 class BufferedZoneList { 311 class BufferedZoneList {
289 public: 312 public:
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 FunctionEntry result(store()->AddBlock(0, FunctionEntry::kSize)); 999 FunctionEntry result(store()->AddBlock(0, FunctionEntry::kSize));
977 result.set_start_pos(start); 1000 result.set_start_pos(start);
978 return result; 1001 return result;
979 } 1002 }
980 1003
981 1004
982 class AstBuildingParser : public Parser { 1005 class AstBuildingParser : public Parser {
983 public: 1006 public:
984 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, 1007 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax,
985 v8::Extension* extension, ScriptDataImpl* pre_data) 1008 v8::Extension* extension, ScriptDataImpl* pre_data)
986 : Parser(script, allow_natives_syntax, extension, false, 1009 : Parser(script, allow_natives_syntax, extension, PARSE,
987 factory(), log(), pre_data) { } 1010 factory(), log(), pre_data) { }
988 virtual void ReportMessageAt(Scanner::Location loc, const char* message, 1011 virtual void ReportMessageAt(Scanner::Location loc, const char* message,
989 Vector<const char*> args); 1012 Vector<const char*> args);
990 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, 1013 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
991 FunctionLiteral* fun, bool resolve, bool* ok); 1014 FunctionLiteral* fun, bool resolve, bool* ok);
992 AstBuildingParserFactory* factory() { return &factory_; } 1015 AstBuildingParserFactory* factory() { return &factory_; }
993 ParserLog* log() { return &log_; } 1016 ParserLog* log() { return &log_; }
994 1017
995 private: 1018 private:
996 ParserLog log_; 1019 ParserLog log_;
997 AstBuildingParserFactory factory_; 1020 AstBuildingParserFactory factory_;
998 }; 1021 };
999 1022
1000 1023
1001 class PreParser : public Parser { 1024 class PreParser : public Parser {
1002 public: 1025 public:
1003 PreParser(Handle<Script> script, bool allow_natives_syntax, 1026 PreParser(Handle<Script> script, bool allow_natives_syntax,
1004 v8::Extension* extension) 1027 v8::Extension* extension)
1005 : Parser(script, allow_natives_syntax, extension, true, 1028 : Parser(script, allow_natives_syntax, extension, PREPARSE,
1006 factory(), recorder(), NULL) 1029 factory(), recorder(), NULL),
1007 , factory_(true) { } 1030 factory_(true) { }
1008 virtual void ReportMessageAt(Scanner::Location loc, const char* message, 1031 virtual void ReportMessageAt(Scanner::Location loc, const char* message,
1009 Vector<const char*> args); 1032 Vector<const char*> args);
1010 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, 1033 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
1011 FunctionLiteral* fun, bool resolve, bool* ok); 1034 FunctionLiteral* fun, bool resolve, bool* ok);
1012 ParserFactory* factory() { return &factory_; } 1035 ParserFactory* factory() { return &factory_; }
1013 ParserRecorder* recorder() { return &recorder_; } 1036 ParserRecorder* recorder() { return &recorder_; }
1014 1037
1015 private: 1038 private:
1016 ParserRecorder recorder_; 1039 ParserRecorder recorder_;
1017 ParserFactory factory_; 1040 ParserFactory factory_;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 ((void)0 1163 ((void)0
1141 #define DUMMY ) // to make indentation work 1164 #define DUMMY ) // to make indentation work
1142 #undef DUMMY 1165 #undef DUMMY
1143 1166
1144 // ---------------------------------------------------------------------------- 1167 // ----------------------------------------------------------------------------
1145 // Implementation of Parser 1168 // Implementation of Parser
1146 1169
1147 Parser::Parser(Handle<Script> script, 1170 Parser::Parser(Handle<Script> script,
1148 bool allow_natives_syntax, 1171 bool allow_natives_syntax,
1149 v8::Extension* extension, 1172 v8::Extension* extension,
1150 bool is_pre_parsing, 1173 ParserMode is_pre_parsing,
1151 ParserFactory* factory, 1174 ParserFactory* factory,
1152 ParserLog* log, 1175 ParserLog* log,
1153 ScriptDataImpl* pre_data) 1176 ScriptDataImpl* pre_data)
1154 : script_(script), 1177 : script_(script),
1155 scanner_(is_pre_parsing), 1178 scanner_(is_pre_parsing),
1156 top_scope_(NULL), 1179 top_scope_(NULL),
1157 with_nesting_level_(0), 1180 with_nesting_level_(0),
1158 temp_scope_(NULL), 1181 temp_scope_(NULL),
1159 target_stack_(NULL), 1182 target_stack_(NULL),
1160 allow_natives_syntax_(allow_natives_syntax), 1183 allow_natives_syntax_(allow_natives_syntax),
1161 extension_(extension), 1184 extension_(extension),
1162 factory_(factory), 1185 factory_(factory),
1163 log_(log), 1186 log_(log),
1164 is_pre_parsing_(is_pre_parsing), 1187 is_pre_parsing_(is_pre_parsing == PREPARSE),
1165 pre_data_(pre_data) { 1188 pre_data_(pre_data) {
1166 } 1189 }
1167 1190
1168 1191
1169 bool Parser::PreParseProgram(Handle<String> source, 1192 bool Parser::PreParseProgram(Handle<String> source,
1170 unibrow::CharacterStream* stream) { 1193 unibrow::CharacterStream* stream) {
1171 HistogramTimerScope timer(&Counters::pre_parse); 1194 HistogramTimerScope timer(&Counters::pre_parse);
1172 AssertNoZoneAllocation assert_no_zone_allocation; 1195 AssertNoZoneAllocation assert_no_zone_allocation;
1173 AssertNoAllocation assert_no_allocation; 1196 AssertNoAllocation assert_no_allocation;
1174 NoHandleAllocation no_handle_allocation; 1197 NoHandleAllocation no_handle_allocation;
1175 scanner_.Init(source, stream, 0); 1198 scanner_.Init(source, stream, 0, JAVASCRIPT);
1176 ASSERT(target_stack_ == NULL); 1199 ASSERT(target_stack_ == NULL);
1177 mode_ = PARSE_EAGERLY; 1200 mode_ = PARSE_EAGERLY;
1178 DummyScope top_scope; 1201 DummyScope top_scope;
1179 LexicalScope scope(this, &top_scope); 1202 LexicalScope scope(this, &top_scope);
1180 TemporaryScope temp_scope(this); 1203 TemporaryScope temp_scope(this);
1181 ZoneListWrapper<Statement> processor; 1204 ZoneListWrapper<Statement> processor;
1182 bool ok = true; 1205 bool ok = true;
1183 ParseSourceElements(&processor, Token::EOS, &ok); 1206 ParseSourceElements(&processor, Token::EOS, &ok);
1184 return !scanner().stack_overflow(); 1207 return !scanner().stack_overflow();
1185 } 1208 }
1186 1209
1187 1210
1188 FunctionLiteral* Parser::ParseProgram(Handle<String> source, 1211 FunctionLiteral* Parser::ParseProgram(Handle<String> source,
1189 unibrow::CharacterStream* stream, 1212 unibrow::CharacterStream* stream,
1190 bool in_global_context) { 1213 bool in_global_context) {
1191 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); 1214 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
1192 1215
1193 HistogramTimerScope timer(&Counters::parse); 1216 HistogramTimerScope timer(&Counters::parse);
1194 Counters::total_parse_size.Increment(source->length()); 1217 Counters::total_parse_size.Increment(source->length());
1195 1218
1196 // Initialize parser state. 1219 // Initialize parser state.
1197 source->TryFlattenIfNotFlat(); 1220 source->TryFlattenIfNotFlat();
1198 scanner_.Init(source, stream, 0); 1221 scanner_.Init(source, stream, 0, JAVASCRIPT);
1199 ASSERT(target_stack_ == NULL); 1222 ASSERT(target_stack_ == NULL);
1200 1223
1201 // Compute the parsing mode. 1224 // Compute the parsing mode.
1202 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; 1225 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
1203 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 1226 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
1204 1227
1205 Scope::Type type = 1228 Scope::Type type =
1206 in_global_context 1229 in_global_context
1207 ? Scope::GLOBAL_SCOPE 1230 ? Scope::GLOBAL_SCOPE
1208 : Scope::EVAL_SCOPE; 1231 : Scope::EVAL_SCOPE;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 Handle<String> name, 1270 Handle<String> name,
1248 int start_position, 1271 int start_position,
1249 bool is_expression) { 1272 bool is_expression) {
1250 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); 1273 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
1251 HistogramTimerScope timer(&Counters::parse_lazy); 1274 HistogramTimerScope timer(&Counters::parse_lazy);
1252 source->TryFlattenIfNotFlat(); 1275 source->TryFlattenIfNotFlat();
1253 Counters::total_parse_size.Increment(source->length()); 1276 Counters::total_parse_size.Increment(source->length());
1254 SafeStringInputBuffer buffer(source.location()); 1277 SafeStringInputBuffer buffer(source.location());
1255 1278
1256 // Initialize parser state. 1279 // Initialize parser state.
1257 scanner_.Init(source, &buffer, start_position); 1280 scanner_.Init(source, &buffer, start_position, JAVASCRIPT);
1258 ASSERT(target_stack_ == NULL); 1281 ASSERT(target_stack_ == NULL);
1259 mode_ = PARSE_EAGERLY; 1282 mode_ = PARSE_EAGERLY;
1260 1283
1261 // Place holder for the result. 1284 // Place holder for the result.
1262 FunctionLiteral* result = NULL; 1285 FunctionLiteral* result = NULL;
1263 1286
1264 { 1287 {
1265 // Parse the function literal. 1288 // Parse the function literal.
1266 Handle<String> no_name = factory()->EmptySymbol(); 1289 Handle<String> no_name = factory()->EmptySymbol();
1267 Scope* scope = 1290 Scope* scope =
(...skipping 15 matching lines...) Expand all
1283 1306
1284 // If there was a stack overflow we have to get rid of AST and it is 1307 // If there was a stack overflow we have to get rid of AST and it is
1285 // not safe to do before scope has been deleted. 1308 // not safe to do before scope has been deleted.
1286 if (result == NULL) { 1309 if (result == NULL) {
1287 Top::StackOverflow(); 1310 Top::StackOverflow();
1288 zone_scope.DeleteOnExit(); 1311 zone_scope.DeleteOnExit();
1289 } 1312 }
1290 return result; 1313 return result;
1291 } 1314 }
1292 1315
1316 FunctionLiteral* Parser::ParseJson(Handle<String> source,
1317 unibrow::CharacterStream* stream) {
1318 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
1319
1320 HistogramTimerScope timer(&Counters::parse);
1321 Counters::total_parse_size.Increment(source->length());
1322
1323 // Initialize parser state.
1324 source->TryFlattenIfNotFlat();
1325 scanner_.Init(source, stream, 0, JSON);
1326 ASSERT(target_stack_ == NULL);
1327
1328 FunctionLiteral* result = NULL;
1329 Handle<String> no_name = factory()->EmptySymbol();
1330
1331 {
1332 Scope* scope = factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, false);
1333 LexicalScope lexical_scope(this, scope);
1334 TemporaryScope temp_scope(this);
1335 bool ok = true;
1336 Expression* expression = ParseJson(&ok);
1337 if (ok) {
1338 ZoneListWrapper<Statement> statement = factory()->NewList<Statement>(1);
1339 statement.Add(new ExpressionStatement(expression));
1340 result = NEW(FunctionLiteral(
1341 no_name,
1342 top_scope_,
1343 statement.elements(),
1344 temp_scope.materialized_literal_count(),
1345 temp_scope.expected_property_count(),
1346 temp_scope.only_simple_this_property_assignments(),
1347 temp_scope.this_property_assignments(),
1348 0,
1349 0,
1350 source->length(),
1351 false));
1352 } else if (scanner().stack_overflow()) {
1353 Top::StackOverflow();
1354 }
1355 }
1356
1357 // Make sure the target stack is empty.
1358 ASSERT(target_stack_ == NULL);
1359
1360 // If there was a syntax error we have to get rid of the AST
1361 // and it is not safe to do so before the scope has been deleted.
1362 if (result == NULL) zone_scope.DeleteOnExit();
1363 return result;
1364 }
1293 1365
1294 void Parser::ReportMessage(const char* type, Vector<const char*> args) { 1366 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
1295 Scanner::Location source_location = scanner_.location(); 1367 Scanner::Location source_location = scanner_.location();
1296 ReportMessageAt(source_location, type, args); 1368 ReportMessageAt(source_location, type, args);
1297 } 1369 }
1298 1370
1299 1371
1300 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, 1372 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location,
1301 const char* type, 1373 const char* type,
1302 Vector<const char*> args) { 1374 Vector<const char*> args) {
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after
3115 3187
3116 Expect(Token::DEBUGGER, CHECK_OK); 3188 Expect(Token::DEBUGGER, CHECK_OK);
3117 ExpectSemicolon(CHECK_OK); 3189 ExpectSemicolon(CHECK_OK);
3118 return NEW(DebuggerStatement()); 3190 return NEW(DebuggerStatement());
3119 } 3191 }
3120 3192
3121 3193
3122 void Parser::ReportUnexpectedToken(Token::Value token) { 3194 void Parser::ReportUnexpectedToken(Token::Value token) {
3123 // We don't report stack overflows here, to avoid increasing the 3195 // We don't report stack overflows here, to avoid increasing the
3124 // stack depth even further. Instead we report it after parsing is 3196 // stack depth even further. Instead we report it after parsing is
3125 // over, in ParseProgram. 3197 // over, in ParseProgram/ParseJson.
3126 if (token == Token::ILLEGAL && scanner().stack_overflow()) 3198 if (token == Token::ILLEGAL && scanner().stack_overflow())
3127 return; 3199 return;
3128 // Four of the tokens are treated specially 3200 // Four of the tokens are treated specially
3129 switch (token) { 3201 switch (token) {
3130 case Token::EOS: 3202 case Token::EOS:
3131 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); 3203 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
3132 case Token::NUMBER: 3204 case Token::NUMBER:
3133 return ReportMessage("unexpected_token_number", 3205 return ReportMessage("unexpected_token_number",
3134 Vector<const char*>::empty()); 3206 Vector<const char*>::empty());
3135 case Token::STRING: 3207 case Token::STRING:
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
3447 // TODO(1240767): Consider allowing trailing comma. 3519 // TODO(1240767): Consider allowing trailing comma.
3448 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 3520 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3449 } 3521 }
3450 Expect(Token::RBRACE, CHECK_OK); 3522 Expect(Token::RBRACE, CHECK_OK);
3451 // Computation of literal_index must happen before pre parse bailout. 3523 // Computation of literal_index must happen before pre parse bailout.
3452 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 3524 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
3453 if (is_pre_parsing_) return NULL; 3525 if (is_pre_parsing_) return NULL;
3454 3526
3455 Handle<FixedArray> constant_properties = 3527 Handle<FixedArray> constant_properties =
3456 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); 3528 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
3457 int position = 0; 3529
3458 bool is_simple = true; 3530 bool is_simple = true;
3459 int depth = 1; 3531 int depth = 1;
3460 for (int i = 0; i < properties.length(); i++) { 3532 BuildObjectLiteralConstantProperties(properties.elements(),
3461 ObjectLiteral::Property* property = properties.at(i); 3533 constant_properties,
3462 if (!IsBoilerplateProperty(property)) { 3534 &is_simple,
3463 is_simple = false; 3535 &depth);
3464 continue;
3465 }
3466 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
3467 if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3468 depth = m_literal->depth() + 1;
3469 }
3470
3471 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
3472 // value for COMPUTED properties, the real value is filled in at
3473 // runtime. The enumeration order is maintained.
3474 Handle<Object> key = property->key()->handle();
3475 Handle<Object> value = GetBoilerplateValue(property->value());
3476 is_simple = is_simple && !value->IsUndefined();
3477
3478 // Add name, value pair to the fixed array.
3479 constant_properties->set(position++, *key);
3480 constant_properties->set(position++, *value);
3481 }
3482
3483 return new ObjectLiteral(constant_properties, 3536 return new ObjectLiteral(constant_properties,
3484 properties.elements(), 3537 properties.elements(),
3485 literal_index, 3538 literal_index,
3486 is_simple, 3539 is_simple,
3487 depth); 3540 depth);
3488 } 3541 }
3489 3542
3490 3543
3491 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { 3544 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
3492 if (!scanner_.ScanRegExpPattern(seen_equal)) { 3545 if (!scanner_.ScanRegExpPattern(seen_equal)) {
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
3713 3766
3714 3767
3715 void Parser::Expect(Token::Value token, bool* ok) { 3768 void Parser::Expect(Token::Value token, bool* ok) {
3716 Token::Value next = Next(); 3769 Token::Value next = Next();
3717 if (next == token) return; 3770 if (next == token) return;
3718 ReportUnexpectedToken(next); 3771 ReportUnexpectedToken(next);
3719 *ok = false; 3772 *ok = false;
3720 } 3773 }
3721 3774
3722 3775
3776 bool Parser::Check(Token::Value token) {
3777 Token::Value next = peek();
3778 if (next == token) {
3779 Consume(next);
3780 return true;
3781 }
3782 return false;
3783 }
3784
3785
3723 void Parser::ExpectSemicolon(bool* ok) { 3786 void Parser::ExpectSemicolon(bool* ok) {
3724 // Check for automatic semicolon insertion according to 3787 // Check for automatic semicolon insertion according to
3725 // the rules given in ECMA-262, section 7.9, page 21. 3788 // the rules given in ECMA-262, section 7.9, page 21.
3726 Token::Value tok = peek(); 3789 Token::Value tok = peek();
3727 if (tok == Token::SEMICOLON) { 3790 if (tok == Token::SEMICOLON) {
3728 Next(); 3791 Next();
3729 return; 3792 return;
3730 } 3793 }
3731 if (scanner_.has_line_terminator_before_next() || 3794 if (scanner_.has_line_terminator_before_next() ||
3732 tok == Token::RBRACE || 3795 tok == Token::RBRACE ||
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
3879 array->SetFastElement(i, *element); 3942 array->SetFastElement(i, *element);
3880 } 3943 }
3881 } 3944 }
3882 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); 3945 ZoneList<Expression*>* args = new ZoneList<Expression*>(2);
3883 args->Add(new Literal(type)); 3946 args->Add(new Literal(type));
3884 args->Add(new Literal(array)); 3947 args->Add(new Literal(array));
3885 return new Throw(new CallRuntime(constructor, NULL, args), 3948 return new Throw(new CallRuntime(constructor, NULL, args),
3886 scanner().location().beg_pos); 3949 scanner().location().beg_pos);
3887 } 3950 }
3888 3951
3952 // ----------------------------------------------------------------------------
3953 // JSON
3954
3955 void Parser::BuildObjectLiteralConstantProperties(
Mads Ager (chromium) 2010/02/01 08:42:19 This is used for normal parsing of object literals
Lasse Reichstein 2010/02/01 12:17:30 Done.
3956 ZoneList<ObjectLiteral::Property*>* properties,
3957 Handle<FixedArray> constant_properties,
3958 bool* is_simple_out,
3959 int* depth_out) {
3960 int position = 0;
3961 bool is_simple = true;
3962 int depth = 1;
3963 for (int i = 0; i < properties->length(); i++) {
3964 ObjectLiteral::Property* property = properties->at(i);
3965 if (!IsBoilerplateProperty(property)) {
3966 is_simple = false;
3967 continue;
3968 }
3969 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
3970 if (m_literal != NULL && m_literal->depth() + 1 > depth) {
3971 depth = m_literal->depth() + 1;
3972 }
3973
3974 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
3975 // value for COMPUTED properties, the real value is filled in at
3976 // runtime. The enumeration order is maintained.
3977 Handle<Object> key = property->key()->handle();
3978 Handle<Object> value = GetBoilerplateValue(property->value());
3979 is_simple = is_simple && !value->IsUndefined();
3980
3981 // Add name, value pair to the fixed array.
3982 constant_properties->set(position++, *key);
3983 constant_properties->set(position++, *value);
3984 }
3985
3986 *is_simple_out = is_simple;
3987 *depth_out = depth;
3988 }
3989
3990
3991 Expression* Parser::ParseJson(bool* ok) {
3992 Expression* result = ParseJsonValue(CHECK_OK);
3993 Expect(Token::EOS, CHECK_OK);
3994 return result;
3995 }
3996
3997
3998 // Parse any JSON value.
3999 Expression* Parser::ParseJsonValue(bool* ok) {
4000 Token::Value token = peek();
4001 switch (token) {
4002 case Token::STRING: {
4003 Consume(Token::STRING);
4004 int literal_length = scanner_.literal_length();
4005 const char* literal_string = scanner_.literal_string();
4006 if (literal_length == 0) {
4007 return NEW(Literal(Factory::empty_string()));
4008 }
4009 Vector<const char> literal(literal_string, literal_length);
4010 return NEW(Literal(Factory::NewStringFromUtf8(literal, TENURED)));
4011 }
4012 case Token::NUMBER: {
4013 Consume(Token::NUMBER);
4014 ASSERT(scanner_.literal_length() > 0);
4015 double value = StringToDouble(scanner_.literal_string(),
4016 NO_FLAGS, // Hex, octal or trailing junk.
4017 OS::nan_value());
4018 return NewNumberLiteral(value);
4019 }
4020 case Token::FALSE_LITERAL:
4021 Consume(Token::FALSE_LITERAL);
4022 return NEW(Literal(Factory::false_value()));
4023 case Token::TRUE_LITERAL:
4024 Consume(Token::TRUE_LITERAL);
4025 return NEW(Literal(Factory::true_value()));
4026 case Token::NULL_LITERAL:
4027 Consume(Token::NULL_LITERAL);
4028 return NEW(Literal(Factory::null_value()));
4029 case Token::LBRACE: {
4030 Expression* result = ParseJsonObject(CHECK_OK);
4031 return result;
4032 }
4033 case Token::LBRACK: {
4034 Expression* result = ParseJsonArray(CHECK_OK);
4035 return result;
4036 }
4037 default:
4038 *ok = false;
4039 ReportUnexpectedToken(token);
4040 return NULL;
4041 }
4042 }
4043
4044
4045 // Parse a JSON object. Scanner must be right after '{' token.
4046 Expression* Parser::ParseJsonObject(bool* ok) {
4047 Consume(Token::LBRACE);
4048 ZoneListWrapper<ObjectLiteral::Property> properties =
4049 factory()->NewList<ObjectLiteral::Property>(4);
4050 int boilerplate_properties = 0;
4051 if (peek() != Token::RBRACE) {
4052 do {
4053 Expect(Token::STRING, CHECK_OK);
4054 Handle<String> key = factory()->LookupSymbol(scanner_.literal_string(),
4055 scanner_.literal_length());
4056 Expect(Token::COLON, CHECK_OK);
4057 Expression* value = ParseJsonValue(CHECK_OK);
4058 Literal* key_literal;
4059 uint32_t index;
4060 if (key->AsArrayIndex(&index)) {
4061 key_literal = NewNumberLiteral(index);
4062 } else {
4063 key_literal = NEW(Literal(key));
4064 }
4065 ObjectLiteral::Property* property =
4066 NEW(ObjectLiteral::Property(key_literal, value));
4067 properties.Add(property);
4068
4069 if (IsBoilerplateProperty(property)) {
4070 boilerplate_properties++;
4071 }
4072 } while (Check(Token::COMMA));
4073 }
4074 Expect(Token::RBRACE, CHECK_OK);
4075
4076 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
4077 if (is_pre_parsing_) return NULL;
4078
4079 Handle<FixedArray> constant_properties =
4080 Factory::NewFixedArray(boilerplate_properties * 2, TENURED);
4081 bool is_simple = true;
4082 int depth = 1;
4083 BuildObjectLiteralConstantProperties(properties.elements(),
4084 constant_properties,
4085 &is_simple,
4086 &depth);
4087 return new ObjectLiteral(constant_properties,
4088 properties.elements(),
4089 literal_index,
4090 is_simple,
4091 depth);
4092 }
4093
4094
4095 void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values,
4096 Handle<FixedArray> literals,
4097 bool* is_simple_out,
4098 int* depth_out) {
4099 // Fill in the literals.
4100 bool is_simple = true;
4101 int depth = 1;
4102 for (int i = 0; i < values->length(); i++) {
4103 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
4104 if (m_literal != NULL && m_literal->depth() + 1 > depth) {
4105 depth = m_literal->depth() + 1;
4106 }
4107 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
4108 if (boilerplate_value->IsUndefined()) {
4109 literals->set_the_hole(i);
4110 is_simple = false;
4111 } else {
4112 literals->set(i, *boilerplate_value);
4113 }
4114 }
4115
4116 *is_simple_out = is_simple;
4117 *depth_out = depth;
4118 }
4119
4120
4121 // Parse a JSON object. Scanner must be right after '[' token.
4122 Expression* Parser::ParseJsonArray(bool* ok) {
4123 Consume(Token::LBRACK);
4124
4125 ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4);
4126 if (peek() != Token::RBRACK) {
4127 do {
4128 Expression* exp = ParseJsonValue(CHECK_OK);
4129 values.Add(exp);
4130 } while (Check(Token::COMMA));
4131 }
4132 Expect(Token::RBRACK, CHECK_OK);
4133
4134 // Update the scope information before the pre-parsing bailout.
4135 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
4136
4137 if (is_pre_parsing_) return NULL;
4138
4139 // Allocate a fixed array with all the literals.
4140 Handle<FixedArray> literals =
4141 Factory::NewFixedArray(values.length(), TENURED);
4142
4143 bool is_simple;
4144 int depth;
4145 BuildArrayLiteralBoilerplateLiterals(values.elements(),
4146 literals,
4147 &is_simple,
4148 &depth);
4149 return NEW(ArrayLiteral(literals, values.elements(),
4150 literal_index, is_simple, depth));
4151 }
4152
3889 4153
3890 // ---------------------------------------------------------------------------- 4154 // ----------------------------------------------------------------------------
3891 // Regular expressions 4155 // Regular expressions
3892 4156
3893 4157
3894 RegExpParser::RegExpParser(FlatStringReader* in, 4158 RegExpParser::RegExpParser(FlatStringReader* in,
3895 Handle<String>* error, 4159 Handle<String>* error,
3896 bool multiline) 4160 bool multiline)
3897 : current_(kEndMarker), 4161 : current_(kEndMarker),
3898 has_more_(true), 4162 has_more_(true),
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after
4754 result->contains_anchor = parser.contains_anchor(); 5018 result->contains_anchor = parser.contains_anchor();
4755 result->capture_count = capture_count; 5019 result->capture_count = capture_count;
4756 } 5020 }
4757 return !parser.failed(); 5021 return !parser.failed();
4758 } 5022 }
4759 5023
4760 5024
4761 FunctionLiteral* MakeAST(bool compile_in_global_context, 5025 FunctionLiteral* MakeAST(bool compile_in_global_context,
4762 Handle<Script> script, 5026 Handle<Script> script,
4763 v8::Extension* extension, 5027 v8::Extension* extension,
4764 ScriptDataImpl* pre_data) { 5028 ScriptDataImpl* pre_data,
5029 bool is_json) {
4765 bool allow_natives_syntax = 5030 bool allow_natives_syntax =
4766 always_allow_natives_syntax || 5031 always_allow_natives_syntax ||
4767 FLAG_allow_natives_syntax || 5032 FLAG_allow_natives_syntax ||
4768 Bootstrapper::IsActive(); 5033 Bootstrapper::IsActive();
4769 AstBuildingParser parser(script, allow_natives_syntax, extension, pre_data); 5034 AstBuildingParser parser(script, allow_natives_syntax, extension, pre_data);
4770 if (pre_data != NULL && pre_data->has_error()) { 5035 if (pre_data != NULL && pre_data->has_error()) {
4771 Scanner::Location loc = pre_data->MessageLocation(); 5036 Scanner::Location loc = pre_data->MessageLocation();
4772 const char* message = pre_data->BuildMessage(); 5037 const char* message = pre_data->BuildMessage();
4773 Vector<const char*> args = pre_data->BuildArgs(); 5038 Vector<const char*> args = pre_data->BuildArgs();
4774 parser.ReportMessageAt(loc, message, args); 5039 parser.ReportMessageAt(loc, message, args);
4775 DeleteArray(message); 5040 DeleteArray(message);
4776 for (int i = 0; i < args.length(); i++) 5041 for (int i = 0; i < args.length(); i++) {
4777 DeleteArray(args[i]); 5042 DeleteArray(args[i]);
5043 }
4778 DeleteArray(args.start()); 5044 DeleteArray(args.start());
4779 return NULL; 5045 return NULL;
4780 } 5046 }
4781 Handle<String> source = Handle<String>(String::cast(script->source())); 5047 Handle<String> source = Handle<String>(String::cast(script->source()));
4782 SafeStringInputBuffer input(source.location()); 5048 SafeStringInputBuffer input(source.location());
4783 FunctionLiteral* result = parser.ParseProgram(source, 5049 FunctionLiteral* result;
4784 &input, compile_in_global_context); 5050 if (is_json) {
5051 ASSERT(compile_in_global_context);
5052 result = parser.ParseJson(source, &input);
5053 } else {
5054 result = parser.ParseProgram(source, &input, compile_in_global_context);
5055 }
4785 return result; 5056 return result;
4786 } 5057 }
4787 5058
4788 5059
4789 FunctionLiteral* MakeLazyAST(Handle<Script> script, 5060 FunctionLiteral* MakeLazyAST(Handle<Script> script,
4790 Handle<String> name, 5061 Handle<String> name,
4791 int start_position, 5062 int start_position,
4792 int end_position, 5063 int end_position,
4793 bool is_expression) { 5064 bool is_expression) {
4794 bool allow_natives_syntax_before = always_allow_natives_syntax; 5065 bool allow_natives_syntax_before = always_allow_natives_syntax;
4795 always_allow_natives_syntax = true; 5066 always_allow_natives_syntax = true;
4796 AstBuildingParser parser(script, true, NULL, NULL); // always allow 5067 AstBuildingParser parser(script, true, NULL, NULL); // always allow
4797 always_allow_natives_syntax = allow_natives_syntax_before; 5068 always_allow_natives_syntax = allow_natives_syntax_before;
4798 // Parse the function by pulling the function source from the script source. 5069 // Parse the function by pulling the function source from the script source.
4799 Handle<String> script_source(String::cast(script->source())); 5070 Handle<String> script_source(String::cast(script->source()));
4800 FunctionLiteral* result = 5071 FunctionLiteral* result =
4801 parser.ParseLazy(SubString(script_source, start_position, end_position), 5072 parser.ParseLazy(SubString(script_source, start_position, end_position),
4802 name, 5073 name,
4803 start_position, 5074 start_position,
4804 is_expression); 5075 is_expression);
4805 return result; 5076 return result;
4806 } 5077 }
4807 5078
4808 5079
4809 #undef NEW 5080 #undef NEW
4810 5081
4811 5082
4812 } } // namespace v8::internal 5083 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698