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

Side by Side Diff: src/parser.cc

Issue 4135004: Separate JSON parsing from the JavaScript parser. (Closed)
Patch Set: Rename GetSymbol. Move ZoneScope. Created 10 years, 1 month 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') | src/runtime.h » ('j') | 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 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 // If there was a stack overflow we have to get rid of AST and it is 1375 // If there was a stack overflow we have to get rid of AST and it is
1376 // not safe to do before scope has been deleted. 1376 // not safe to do before scope has been deleted.
1377 if (result == NULL) { 1377 if (result == NULL) {
1378 Top::StackOverflow(); 1378 Top::StackOverflow();
1379 zone_scope.DeleteOnExit(); 1379 zone_scope.DeleteOnExit();
1380 } 1380 }
1381 return result; 1381 return result;
1382 } 1382 }
1383 1383
1384 1384
1385 FunctionLiteral* Parser::ParseJson(Handle<String> source) {
1386 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
1387
1388 HistogramTimerScope timer(&Counters::parse);
1389 Counters::total_parse_size.Increment(source->length());
1390
1391 // Initialize parser state.
1392 source->TryFlatten(TENURED);
1393 scanner_.Initialize(source, JSON);
1394 ASSERT(target_stack_ == NULL);
1395
1396 FunctionLiteral* result = NULL;
1397 Handle<String> no_name = factory()->EmptySymbol();
1398
1399 {
1400 Scope* scope = factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, false);
1401 LexicalScope lexical_scope(this, scope);
1402 TemporaryScope temp_scope(this);
1403 bool ok = true;
1404 Expression* expression = ParseJson(&ok);
1405 if (ok) {
1406 ZoneListWrapper<Statement> statement = factory()->NewList<Statement>(1);
1407 statement.Add(new ExpressionStatement(expression));
1408 result = NEW(FunctionLiteral(
1409 no_name,
1410 top_scope_,
1411 statement.elements(),
1412 temp_scope.materialized_literal_count(),
1413 temp_scope.expected_property_count(),
1414 temp_scope.only_simple_this_property_assignments(),
1415 temp_scope.this_property_assignments(),
1416 0,
1417 0,
1418 source->length(),
1419 false,
1420 temp_scope.ContainsLoops()));
1421 } else if (scanner().stack_overflow()) {
1422 Top::StackOverflow();
1423 }
1424 }
1425
1426 // Make sure the target stack is empty.
1427 ASSERT(target_stack_ == NULL);
1428
1429 // If there was a syntax error we have to get rid of the AST
1430 // and it is not safe to do so before the scope has been deleted.
1431 if (result == NULL) zone_scope.DeleteOnExit();
1432 return result;
1433 }
1434
1435 void Parser::ReportMessage(const char* type, Vector<const char*> args) { 1385 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
1436 Scanner::Location source_location = scanner_.location(); 1386 Scanner::Location source_location = scanner_.location();
1437 ReportMessageAt(source_location, type, args); 1387 ReportMessageAt(source_location, type, args);
1438 } 1388 }
1439 1389
1440 1390
1441 Handle<String> Parser::GetSymbol(bool* ok) { 1391 Handle<String> Parser::GetSymbol(bool* ok) {
1442 if (is_pre_parsing_) { 1392 if (is_pre_parsing_) {
1443 log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal()); 1393 log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
1444 return Handle<String>::null(); 1394 return Handle<String>::null();
(...skipping 2831 matching lines...) Expand 10 before | Expand all | Expand 10 after
4276 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); 4226 ZoneList<Expression*>* args = new ZoneList<Expression*>(2);
4277 args->Add(new Literal(type)); 4227 args->Add(new Literal(type));
4278 args->Add(new Literal(array)); 4228 args->Add(new Literal(array));
4279 return new Throw(new CallRuntime(constructor, NULL, args), 4229 return new Throw(new CallRuntime(constructor, NULL, args),
4280 scanner().location().beg_pos); 4230 scanner().location().beg_pos);
4281 } 4231 }
4282 4232
4283 // ---------------------------------------------------------------------------- 4233 // ----------------------------------------------------------------------------
4284 // JSON 4234 // JSON
4285 4235
4286 Expression* Parser::ParseJson(bool* ok) { 4236 Handle<Object> JsonParser::ParseJson(Handle<String> source) {
4287 Expression* result = ParseJsonValue(CHECK_OK); 4237 source->TryFlatten();
4288 Expect(Token::EOS, CHECK_OK); 4238 scanner_.Initialize(source, JSON);
4239 Handle<Object> result = ParseJsonValue();
4240 if (result.is_null() || scanner_.Next() != Token::EOS) {
4241 if (scanner_.stack_overflow()) {
4242 // Scanner failed.
4243 Top::StackOverflow();
4244 } else {
4245 // Parse failed. Scanner's current token is the unexpected token.
4246 Token::Value token = scanner_.current_token();
4247
4248 const char* message;
4249 const char* name_opt = NULL;
4250
4251 switch (token) {
4252 case Token::EOS:
4253 message = "unexpected_eos";
4254 break;
4255 case Token::NUMBER:
4256 message = "unexpected_token_number";
4257 break;
4258 case Token::STRING:
4259 message = "unexpected_token_string";
4260 break;
4261 case Token::IDENTIFIER:
4262 message = "unexpected_token_identifier";
4263 break;
4264 default:
4265 message = "unexpected_token";
4266 name_opt = Token::String(token);
4267 ASSERT(name_opt != NULL);
4268 break;
4269 }
4270
4271 Scanner::Location source_location = scanner_.location();
4272 MessageLocation location(Factory::NewScript(source),
4273 source_location.beg_pos,
4274 source_location.end_pos);
4275 int argc = (name_opt == NULL) ? 0 : 1;
4276 Handle<JSArray> array = Factory::NewJSArray(argc);
4277 if (name_opt != NULL) {
4278 SetElement(array,
4279 0,
4280 Factory::NewStringFromUtf8(CStrVector(name_opt)));
4281 }
4282 Handle<Object> result = Factory::NewSyntaxError(message, array);
4283 Top::Throw(*result, &location);
4284 return Handle<Object>::null();
4285 }
4286 }
4289 return result; 4287 return result;
4290 } 4288 }
4291 4289
4292 4290
4291 Handle<String> JsonParser::GetString() {
4292 int literal_length = scanner_.literal_length();
4293 if (literal_length == 0) {
4294 return Factory::empty_string();
4295 }
4296 const char* literal_string = scanner_.literal_string();
4297 Vector<const char> literal(literal_string, literal_length);
4298 return Factory::NewStringFromUtf8(literal);
4299 }
4300
4301
4293 // Parse any JSON value. 4302 // Parse any JSON value.
4294 Expression* Parser::ParseJsonValue(bool* ok) { 4303 Handle<Object> JsonParser::ParseJsonValue() {
4295 Token::Value token = peek(); 4304 Token::Value token = scanner_.Next();
4296 switch (token) { 4305 switch (token) {
4297 case Token::STRING: { 4306 case Token::STRING: {
4298 Consume(Token::STRING); 4307 return GetString();
4299 int literal_length = scanner_.literal_length();
4300 const char* literal_string = scanner_.literal_string();
4301 if (literal_length == 0) {
4302 return NEW(Literal(Factory::empty_string()));
4303 }
4304 Vector<const char> literal(literal_string, literal_length);
4305 return NEW(Literal(Factory::NewStringFromUtf8(literal, TENURED)));
4306 } 4308 }
4307 case Token::NUMBER: { 4309 case Token::NUMBER: {
4308 Consume(Token::NUMBER);
4309 ASSERT(scanner_.literal_length() > 0);
4310 double value = StringToDouble(scanner_.literal(), 4310 double value = StringToDouble(scanner_.literal(),
4311 NO_FLAGS, // Hex, octal or trailing junk. 4311 NO_FLAGS, // Hex, octal or trailing junk.
4312 OS::nan_value()); 4312 OS::nan_value());
4313 return NewNumberLiteral(value); 4313 return Factory::NewNumber(value);
4314 } 4314 }
4315 case Token::FALSE_LITERAL: 4315 case Token::FALSE_LITERAL:
4316 Consume(Token::FALSE_LITERAL); 4316 return Factory::false_value();
4317 return NEW(Literal(Factory::false_value()));
4318 case Token::TRUE_LITERAL: 4317 case Token::TRUE_LITERAL:
4319 Consume(Token::TRUE_LITERAL); 4318 return Factory::true_value();
4320 return NEW(Literal(Factory::true_value()));
4321 case Token::NULL_LITERAL: 4319 case Token::NULL_LITERAL:
4322 Consume(Token::NULL_LITERAL); 4320 return Factory::null_value();
4323 return NEW(Literal(Factory::null_value())); 4321 case Token::LBRACE:
4324 case Token::LBRACE: { 4322 return ParseJsonObject();
4325 Expression* result = ParseJsonObject(CHECK_OK); 4323 case Token::LBRACK:
4326 return result; 4324 return ParseJsonArray();
4327 }
4328 case Token::LBRACK: {
4329 Expression* result = ParseJsonArray(CHECK_OK);
4330 return result;
4331 }
4332 default: 4325 default:
4333 *ok = false; 4326 return ReportUnexpectedToken();
4334 ReportUnexpectedToken(token);
4335 return NULL;
4336 } 4327 }
4337 } 4328 }
4338 4329
4339 4330
4340 // Parse a JSON object. Scanner must be right after '{' token. 4331 // Parse a JSON object. Scanner must be right after '{' token.
4341 Expression* Parser::ParseJsonObject(bool* ok) { 4332 Handle<Object> JsonParser::ParseJsonObject() {
4342 Consume(Token::LBRACE); 4333 Handle<JSFunction> object_constructor(
4343 ZoneListWrapper<ObjectLiteral::Property> properties = 4334 Top::global_context()->object_function());
4344 factory()->NewList<ObjectLiteral::Property>(4); 4335 Handle<JSObject> json_object = Factory::NewJSObject(object_constructor);
4345 int boilerplate_properties = 0; 4336 if (scanner_.peek() == Token::RBRACE) {
4346 if (peek() != Token::RBRACE) { 4337 scanner_.Next();
4338 } else {
4347 do { 4339 do {
4348 Expect(Token::STRING, CHECK_OK); 4340 if (scanner_.Next() != Token::STRING) {
4349 Handle<String> key = GetSymbol(CHECK_OK); 4341 return ReportUnexpectedToken();
4350 Expect(Token::COLON, CHECK_OK); 4342 }
4351 Expression* value = ParseJsonValue(CHECK_OK); 4343 Handle<String> key = GetString();
4352 Literal* key_literal; 4344 if (scanner_.Next() != Token::COLON) {
4345 return ReportUnexpectedToken();
4346 }
4347 Handle<Object> value = ParseJsonValue();
4348 if (value.is_null()) return Handle<Object>::null();
4353 uint32_t index; 4349 uint32_t index;
4354 if (key->AsArrayIndex(&index)) { 4350 if (key->AsArrayIndex(&index)) {
4355 key_literal = NewNumberLiteral(index); 4351 SetElement(json_object, index, value);
4356 } else { 4352 } else {
4357 key_literal = NEW(Literal(key)); 4353 SetProperty(json_object, key, value, NONE);
4358 } 4354 }
4359 ObjectLiteral::Property* property = 4355 } while (scanner_.Next() == Token::COMMA);
4360 NEW(ObjectLiteral::Property(key_literal, value)); 4356 if (scanner_.current_token() != Token::RBRACE) {
4361 properties.Add(property); 4357 return ReportUnexpectedToken();
4362 4358 }
4363 if (IsBoilerplateProperty(property)) {
4364 boilerplate_properties++;
4365 }
4366 } while (Check(Token::COMMA));
4367 } 4359 }
4368 Expect(Token::RBRACE, CHECK_OK); 4360 return json_object;
4369
4370 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
4371 if (is_pre_parsing_) return NULL;
4372
4373 Handle<FixedArray> constant_properties =
4374 Factory::NewFixedArray(boilerplate_properties * 2, TENURED);
4375 bool is_simple = true;
4376 bool fast_elements = true;
4377 int depth = 1;
4378 BuildObjectLiteralConstantProperties(properties.elements(),
4379 constant_properties,
4380 &is_simple,
4381 &fast_elements,
4382 &depth);
4383 return new ObjectLiteral(constant_properties,
4384 properties.elements(),
4385 literal_index,
4386 is_simple,
4387 fast_elements,
4388 depth);
4389 } 4361 }
4390 4362
4391 4363
4392 // Parse a JSON array. Scanner must be right after '[' token. 4364 // Parse a JSON array. Scanner must be right after '[' token.
4393 Expression* Parser::ParseJsonArray(bool* ok) { 4365 Handle<Object> JsonParser::ParseJsonArray() {
4394 Consume(Token::LBRACK); 4366 ZoneScope zone_scope(DELETE_ON_EXIT);
4367 ZoneList<Handle<Object> > elements(4);
4395 4368
4396 ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4); 4369 Token::Value token = scanner_.peek();
4397 if (peek() != Token::RBRACK) { 4370 if (token == Token::RBRACK) {
4371 scanner_.Next();
4372 } else {
4398 do { 4373 do {
4399 Expression* exp = ParseJsonValue(CHECK_OK); 4374 Handle<Object> element = ParseJsonValue();
4400 values.Add(exp); 4375 if (element.is_null()) return Handle<Object>::null();
4401 } while (Check(Token::COMMA)); 4376 elements.Add(element);
4377 token = scanner_.Next();
4378 } while (token == Token::COMMA);
4379 if (token != Token::RBRACK) {
4380 return ReportUnexpectedToken();
4381 }
4402 } 4382 }
4403 Expect(Token::RBRACK, CHECK_OK);
4404 4383
4405 // Update the scope information before the pre-parsing bailout. 4384 // Allocate a fixed array with all the elements.
4406 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 4385 Handle<FixedArray> fast_elements =
4386 Factory::NewFixedArray(elements.length());
4407 4387
4408 if (is_pre_parsing_) return NULL; 4388 for (int i = 0, n = elements.length(); i < n; i++) {
4389 fast_elements->set(i, *elements[i]);
4390 }
4409 4391
4410 // Allocate a fixed array with all the literals. 4392 return Factory::NewJSArrayWithElements(fast_elements);
4411 Handle<FixedArray> literals =
4412 Factory::NewFixedArray(values.length(), TENURED);
4413
4414 bool is_simple;
4415 int depth;
4416 BuildArrayLiteralBoilerplateLiterals(values.elements(),
4417 literals,
4418 &is_simple,
4419 &depth);
4420 return NEW(ArrayLiteral(literals, values.elements(),
4421 literal_index, is_simple, depth));
4422 } 4393 }
4423 4394
4424
4425 // ---------------------------------------------------------------------------- 4395 // ----------------------------------------------------------------------------
4426 // Regular expressions 4396 // Regular expressions
4427 4397
4428 4398
4429 RegExpParser::RegExpParser(FlatStringReader* in, 4399 RegExpParser::RegExpParser(FlatStringReader* in,
4430 Handle<String>* error, 4400 Handle<String>* error,
4431 bool multiline) 4401 bool multiline)
4432 : current_(kEndMarker), 4402 : current_(kEndMarker),
4433 has_more_(true), 4403 has_more_(true),
4434 multiline_(multiline), 4404 multiline_(multiline),
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after
5363 Vector<const char*> args = pre_data->BuildArgs(); 5333 Vector<const char*> args = pre_data->BuildArgs();
5364 parser.ReportMessageAt(loc, message, args); 5334 parser.ReportMessageAt(loc, message, args);
5365 DeleteArray(message); 5335 DeleteArray(message);
5366 for (int i = 0; i < args.length(); i++) { 5336 for (int i = 0; i < args.length(); i++) {
5367 DeleteArray(args[i]); 5337 DeleteArray(args[i]);
5368 } 5338 }
5369 DeleteArray(args.start()); 5339 DeleteArray(args.start());
5370 ASSERT(Top::has_pending_exception()); 5340 ASSERT(Top::has_pending_exception());
5371 } else { 5341 } else {
5372 Handle<String> source = Handle<String>(String::cast(script->source())); 5342 Handle<String> source = Handle<String>(String::cast(script->source()));
5373 // JSON is always global. 5343 result = parser.ParseProgram(source, info->is_global());
5374 ASSERT(!info->is_json() || info->is_global());
5375 result = info->is_json()
5376 ? parser.ParseJson(source)
5377 : parser.ParseProgram(source, info->is_global());
5378 } 5344 }
5379 } 5345 }
5380 5346
5381 info->SetFunction(result); 5347 info->SetFunction(result);
5382 return (result != NULL); 5348 return (result != NULL);
5383 } 5349 }
5384 5350
5385 #undef NEW 5351 #undef NEW
5386 5352
5387 } } // namespace v8::internal 5353 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698