| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 2331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2342 AstNode* arg = ctor_args->NodeAt(i); | 2342 AstNode* arg = ctor_args->NodeAt(i); |
| 2343 if (!IsSimpleLocalOrLiteralNode(arg)) { | 2343 if (!IsSimpleLocalOrLiteralNode(arg)) { |
| 2344 LocalVariable* temp = | 2344 LocalVariable* temp = |
| 2345 CreateTempConstVariable(arg->token_pos(), "sca"); | 2345 CreateTempConstVariable(arg->token_pos(), "sca"); |
| 2346 AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg); | 2346 AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg); |
| 2347 ctor_args->SetNodeAt(i, save_temp); | 2347 ctor_args->SetNodeAt(i, save_temp); |
| 2348 } | 2348 } |
| 2349 } | 2349 } |
| 2350 } | 2350 } |
| 2351 OpenBlock(); // Block to collect constructor body nodes. | 2351 OpenBlock(); // Block to collect constructor body nodes. |
| 2352 intptr_t body_pos = TokenPos(); |
| 2352 | 2353 |
| 2353 // Insert the implicit super call to the super constructor body. | 2354 // Insert the implicit super call to the super constructor body. |
| 2354 if (super_call != NULL) { | 2355 if (super_call != NULL) { |
| 2355 ArgumentListNode* initializer_args = super_call->arguments(); | 2356 ArgumentListNode* initializer_args = super_call->arguments(); |
| 2356 const Function& super_ctor = super_call->function(); | 2357 const Function& super_ctor = super_call->function(); |
| 2357 // Patch the initializer call so it only executes the super initializer. | 2358 // Patch the initializer call so it only executes the super initializer. |
| 2358 initializer_args->SetNodeAt(1, | 2359 initializer_args->SetNodeAt(1, |
| 2359 new LiteralNode(TokenPos(), | 2360 new LiteralNode(body_pos, |
| 2360 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); | 2361 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); |
| 2361 | 2362 |
| 2362 ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos()); | 2363 ArgumentListNode* super_call_args = new ArgumentListNode(body_pos); |
| 2363 // First argument is the receiver. | 2364 // First argument is the receiver. |
| 2364 super_call_args->Add(new LoadLocalNode(TokenPos(), receiver)); | 2365 super_call_args->Add(new LoadLocalNode(body_pos, receiver)); |
| 2365 // Second argument is the construction phase argument. | 2366 // Second argument is the construction phase argument. |
| 2366 AstNode* phase_parameter = | 2367 AstNode* phase_parameter = |
| 2367 new LiteralNode(TokenPos(), | 2368 new LiteralNode(body_pos, |
| 2368 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); | 2369 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); |
| 2369 super_call_args->Add(phase_parameter); | 2370 super_call_args->Add(phase_parameter); |
| 2370 super_call_args->set_names(initializer_args->names()); | 2371 super_call_args->set_names(initializer_args->names()); |
| 2371 for (int i = 2; i < initializer_args->length(); i++) { | 2372 for (int i = 2; i < initializer_args->length(); i++) { |
| 2372 AstNode* arg = initializer_args->NodeAt(i); | 2373 AstNode* arg = initializer_args->NodeAt(i); |
| 2373 if (arg->IsLiteralNode()) { | 2374 if (arg->IsLiteralNode()) { |
| 2374 LiteralNode* lit = arg->AsLiteralNode(); | 2375 LiteralNode* lit = arg->AsLiteralNode(); |
| 2375 super_call_args->Add(new LiteralNode(TokenPos(), lit->literal())); | 2376 super_call_args->Add(new LiteralNode(body_pos, lit->literal())); |
| 2376 } else { | 2377 } else { |
| 2377 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); | 2378 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); |
| 2378 if (arg->IsLoadLocalNode()) { | 2379 if (arg->IsLoadLocalNode()) { |
| 2379 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); | 2380 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); |
| 2380 super_call_args->Add(new LoadLocalNode(TokenPos(), &temp)); | 2381 super_call_args->Add(new LoadLocalNode(body_pos, &temp)); |
| 2381 } else if (arg->IsStoreLocalNode()) { | 2382 } else if (arg->IsStoreLocalNode()) { |
| 2382 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); | 2383 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); |
| 2383 super_call_args->Add(new LoadLocalNode(TokenPos(), &temp)); | 2384 super_call_args->Add(new LoadLocalNode(body_pos, &temp)); |
| 2384 } | 2385 } |
| 2385 } | 2386 } |
| 2386 } | 2387 } |
| 2387 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), | 2388 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), |
| 2388 super_call_args->names(), | 2389 super_call_args->names(), |
| 2389 NULL)); | 2390 NULL)); |
| 2390 current_block_->statements->Add( | 2391 current_block_->statements->Add( |
| 2391 new StaticCallNode(TokenPos(), super_ctor, super_call_args)); | 2392 new StaticCallNode(body_pos, super_ctor, super_call_args)); |
| 2392 } | 2393 } |
| 2393 | 2394 |
| 2394 if (CurrentToken() == Token::kLBRACE) { | 2395 if (CurrentToken() == Token::kLBRACE) { |
| 2395 ConsumeToken(); | 2396 ConsumeToken(); |
| 2396 ParseStatementSequence(); | 2397 ParseStatementSequence(); |
| 2397 ExpectToken(Token::kRBRACE); | 2398 ExpectToken(Token::kRBRACE); |
| 2398 } else if (CurrentToken() == Token::kARROW) { | 2399 } else if (CurrentToken() == Token::kARROW) { |
| 2399 ErrorMsg("constructors may not return a value"); | 2400 ErrorMsg("constructors may not return a value"); |
| 2400 } else if (IsLiteral("native")) { | 2401 } else if (IsLiteral("native")) { |
| 2401 ErrorMsg("native constructors not supported"); | 2402 ErrorMsg("native constructors not supported"); |
| 2402 } else if (CurrentToken() == Token::kSEMICOLON) { | 2403 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 2403 // Some constructors have no function body. | 2404 // Some constructors have no function body. |
| 2404 ConsumeToken(); | 2405 ConsumeToken(); |
| 2405 } else { | 2406 } else { |
| 2406 UnexpectedToken(); | 2407 UnexpectedToken(); |
| 2407 } | 2408 } |
| 2408 | 2409 |
| 2409 SequenceNode* ctor_block = CloseBlock(); | 2410 SequenceNode* ctor_block = CloseBlock(); |
| 2410 if (ctor_block->length() > 0) { | 2411 if (ctor_block->length() > 0) { |
| 2411 // Generate guard around the constructor body code. | 2412 // Generate guard around the constructor body code. |
| 2412 LocalVariable* phase_param = LookupPhaseParameter(); | 2413 LocalVariable* phase_param = LookupPhaseParameter(); |
| 2413 AstNode* phase_value = new LoadLocalNode(TokenPos(), phase_param); | 2414 AstNode* phase_value = new LoadLocalNode(body_pos, phase_param); |
| 2414 AstNode* phase_check = | 2415 AstNode* phase_check = |
| 2415 new BinaryOpNode(TokenPos(), Token::kBIT_AND, | 2416 new BinaryOpNode(body_pos, Token::kBIT_AND, |
| 2416 phase_value, | 2417 phase_value, |
| 2417 new LiteralNode(TokenPos(), | 2418 new LiteralNode(body_pos, |
| 2418 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); | 2419 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); |
| 2419 AstNode* comparison = | 2420 AstNode* comparison = |
| 2420 new ComparisonNode(TokenPos(), Token::kNE_STRICT, | 2421 new ComparisonNode(body_pos, Token::kNE_STRICT, |
| 2421 phase_check, | 2422 phase_check, |
| 2422 new LiteralNode(TokenPos(), | 2423 new LiteralNode(body_pos, |
| 2423 Smi::ZoneHandle(Smi::New(0)))); | 2424 Smi::ZoneHandle(Smi::New(0)))); |
| 2424 AstNode* guarded_block_statements = | 2425 AstNode* guarded_block_statements = |
| 2425 new IfNode(TokenPos(), comparison, ctor_block, NULL); | 2426 new IfNode(body_pos, comparison, ctor_block, NULL); |
| 2426 current_block_->statements->Add(guarded_block_statements); | 2427 current_block_->statements->Add(guarded_block_statements); |
| 2427 } | 2428 } |
| 2428 | 2429 |
| 2429 SequenceNode* statements = CloseBlock(); | 2430 SequenceNode* statements = CloseBlock(); |
| 2430 return statements; | 2431 return statements; |
| 2431 } | 2432 } |
| 2432 | 2433 |
| 2433 | 2434 |
| 2434 // Parser is at the opening parenthesis of the formal parameter | 2435 // Parser is at the opening parenthesis of the formal parameter |
| 2435 // declaration of the function or constructor. | 2436 // declaration of the function or constructor. |
| (...skipping 2437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4873 return from_scope->LookupVariable(Symbols::This(), test_only); | 4874 return from_scope->LookupVariable(Symbols::This(), test_only); |
| 4874 } | 4875 } |
| 4875 | 4876 |
| 4876 | 4877 |
| 4877 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, | 4878 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, |
| 4878 bool test_only) { | 4879 bool test_only) { |
| 4879 ASSERT(current_function().IsInFactoryScope()); | 4880 ASSERT(current_function().IsInFactoryScope()); |
| 4880 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), | 4881 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), |
| 4881 test_only); | 4882 test_only); |
| 4882 } | 4883 } |
| 4884 |
| 4885 |
| 4883 LocalVariable* Parser::LookupPhaseParameter() { | 4886 LocalVariable* Parser::LookupPhaseParameter() { |
| 4884 const bool kTestOnly = false; | 4887 const bool kTestOnly = false; |
| 4885 return current_block_->scope->LookupVariable(Symbols::PhaseParameter(), | 4888 return current_block_->scope->LookupVariable(Symbols::PhaseParameter(), |
| 4886 kTestOnly); | 4889 kTestOnly); |
| 4887 } | 4890 } |
| 4888 | 4891 |
| 4889 | 4892 |
| 4890 void Parser::CaptureInstantiator() { | 4893 void Parser::CaptureInstantiator() { |
| 4891 ASSERT(current_block_->scope->function_level() > 0); | 4894 ASSERT(current_block_->scope->function_level() > 0); |
| 4892 const bool kTestOnly = false; | 4895 const bool kTestOnly = false; |
| (...skipping 5083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9976 void Parser::SkipQualIdent() { | 9979 void Parser::SkipQualIdent() { |
| 9977 ASSERT(IsIdentifier()); | 9980 ASSERT(IsIdentifier()); |
| 9978 ConsumeToken(); | 9981 ConsumeToken(); |
| 9979 if (CurrentToken() == Token::kPERIOD) { | 9982 if (CurrentToken() == Token::kPERIOD) { |
| 9980 ConsumeToken(); // Consume the kPERIOD token. | 9983 ConsumeToken(); // Consume the kPERIOD token. |
| 9981 ExpectIdentifier("identifier expected after '.'"); | 9984 ExpectIdentifier("identifier expected after '.'"); |
| 9982 } | 9985 } |
| 9983 } | 9986 } |
| 9984 | 9987 |
| 9985 } // namespace dart | 9988 } // namespace dart |
| OLD | NEW |