OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |