| 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 |