Chromium Code Reviews| 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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 } | 107 } |
| 108 | 108 |
| 109 | 109 |
| 110 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) { | 110 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) { |
| 111 return new LocalVariable(token_pos, | 111 return new LocalVariable(token_pos, |
| 112 Symbols::ExprTemp(), | 112 Symbols::ExprTemp(), |
| 113 Type::ZoneHandle(Type::DynamicType())); | 113 Type::ZoneHandle(Type::DynamicType())); |
| 114 } | 114 } |
| 115 | 115 |
| 116 | 116 |
| 117 LocalVariable* ParsedFunction::CreateArrayLiteralVar(intptr_t token_pos) { | |
| 118 return new LocalVariable(token_pos, | |
| 119 Symbols::ArrayLiteralVar(), | |
| 120 Type::ZoneHandle(Type::ArrayType())); | |
| 121 } | |
| 122 | |
| 123 | |
| 117 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 124 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
| 118 ASSERT(node_sequence_ == NULL); | 125 ASSERT(node_sequence_ == NULL); |
| 119 ASSERT(node_sequence != NULL); | 126 ASSERT(node_sequence != NULL); |
| 120 node_sequence_ = node_sequence; | 127 node_sequence_ = node_sequence; |
| 121 } | 128 } |
| 122 | 129 |
| 123 | 130 |
| 124 LocalVariable* ParsedFunction::GetSavedArgumentsDescriptorVar() const { | 131 LocalVariable* ParsedFunction::GetSavedArgumentsDescriptorVar() const { |
| 125 const int num_parameters = function().NumParameters(); | 132 const int num_parameters = function().NumParameters(); |
| 126 LocalScope* scope = node_sequence()->scope(); | 133 LocalScope* scope = node_sequence()->scope(); |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 751 case RawFunction::kConstImplicitGetter: | 758 case RawFunction::kConstImplicitGetter: |
| 752 node_sequence = parser.ParseStaticConstGetter(func); | 759 node_sequence = parser.ParseStaticConstGetter(func); |
| 753 break; | 760 break; |
| 754 case RawFunction::kMethodExtractor: | 761 case RawFunction::kMethodExtractor: |
| 755 node_sequence = parser.ParseMethodExtractor(func); | 762 node_sequence = parser.ParseMethodExtractor(func); |
| 756 break; | 763 break; |
| 757 default: | 764 default: |
| 758 UNREACHABLE(); | 765 UNREACHABLE(); |
| 759 } | 766 } |
| 760 | 767 |
| 768 parsed_function->set_array_literal_var( | |
|
hausner
2013/02/13 00:47:30
I don't like that you have to allocate a variable
srdjan
2013/02/13 01:15:00
I don't like it either, but could not come up with
| |
| 769 ParsedFunction::CreateArrayLiteralVar(func.token_pos())); | |
| 770 node_sequence->scope()->AddVariable(parsed_function->array_literal_var()); | |
| 771 | |
| 761 if (!HasReturnNode(node_sequence)) { | 772 if (!HasReturnNode(node_sequence)) { |
| 762 // Add implicit return node. | 773 // Add implicit return node. |
| 763 node_sequence->Add(new ReturnNode(func.end_token_pos())); | 774 node_sequence->Add(new ReturnNode(func.end_token_pos())); |
| 764 } | 775 } |
| 765 if (parsed_function->has_expression_temp_var()) { | 776 if (parsed_function->has_expression_temp_var()) { |
| 766 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | 777 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); |
| 767 } | 778 } |
| 768 if (parsed_function->has_saved_current_context_var()) { | 779 if (parsed_function->has_saved_current_context_var()) { |
| 769 node_sequence->scope()->AddVariable( | 780 node_sequence->scope()->AddVariable( |
| 770 parsed_function->saved_current_context_var()); | 781 parsed_function->saved_current_context_var()); |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1368 } | 1379 } |
| 1369 | 1380 |
| 1370 | 1381 |
| 1371 static const String& PrivateCoreLibName(const String& str) { | 1382 static const String& PrivateCoreLibName(const String& str) { |
| 1372 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1383 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1373 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); | 1384 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); |
| 1374 return private_name; | 1385 return private_name; |
| 1375 } | 1386 } |
| 1376 | 1387 |
| 1377 | 1388 |
| 1389 LocalVariable* Parser::BuildArrayTempLocal(intptr_t token_pos) { | |
| 1390 char name[64]; | |
| 1391 OS::SNPrint(name, 64, ":arrlit%"Pd, token_pos); | |
| 1392 LocalVariable* temp = | |
| 1393 new LocalVariable(token_pos, | |
| 1394 String::ZoneHandle(Symbols::New(name)), | |
| 1395 Type::ZoneHandle(Type::ArrayType())); | |
| 1396 current_block_->scope->AddVariable(temp); | |
| 1397 return temp; | |
| 1398 } | |
| 1399 | |
| 1400 | |
| 1378 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 1401 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
| 1379 intptr_t call_pos, | 1402 intptr_t call_pos, |
| 1380 const String& function_name, | 1403 const String& function_name, |
| 1381 const ArgumentListNode& function_args) { | 1404 const ArgumentListNode& function_args) { |
| 1382 const intptr_t args_pos = function_args.token_pos(); | 1405 const intptr_t args_pos = function_args.token_pos(); |
| 1383 // Build arguments to the call to the static | 1406 // Build arguments to the call to the static |
| 1384 // InvocationMirror._allocateInvocationMirror method. | 1407 // InvocationMirror._allocateInvocationMirror method. |
| 1385 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 1408 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| 1386 // The first argument is the original function name. | 1409 // The first argument is the original function name. |
| 1387 arguments->Add(new LiteralNode(args_pos, function_name)); | 1410 arguments->Add(new LiteralNode(args_pos, function_name)); |
| 1388 // The second argument is the arguments descriptor of the original function. | 1411 // The second argument is the arguments descriptor of the original function. |
| 1389 const Array& args_descriptor = | 1412 const Array& args_descriptor = |
| 1390 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), | 1413 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), |
| 1391 function_args.names())); | 1414 function_args.names())); |
| 1392 arguments->Add(new LiteralNode(args_pos, args_descriptor)); | 1415 arguments->Add(new LiteralNode(args_pos, args_descriptor)); |
| 1393 // The third argument is an array containing the original function arguments, | 1416 // The third argument is an array containing the original function arguments, |
| 1394 // including the receiver. | 1417 // including the receiver. |
| 1395 ArrayNode* args_array = new ArrayNode( | 1418 ArrayNode* args_array = new ArrayNode( |
| 1396 args_pos, Type::ZoneHandle(Type::ArrayType())); | 1419 args_pos, Type::ZoneHandle(Type::ArrayType()), |
| 1420 *BuildArrayTempLocal(call_pos)); | |
| 1397 for (intptr_t i = 0; i < function_args.length(); i++) { | 1421 for (intptr_t i = 0; i < function_args.length(); i++) { |
| 1398 args_array->AddElement(function_args.NodeAt(i)); | 1422 args_array->AddElement(function_args.NodeAt(i)); |
| 1399 } | 1423 } |
| 1400 arguments->Add(args_array); | 1424 arguments->Add(args_array); |
| 1401 // Lookup the static InvocationMirror._allocateInvocationMirror method. | 1425 // Lookup the static InvocationMirror._allocateInvocationMirror method. |
| 1402 const Class& mirror_class = | 1426 const Class& mirror_class = |
| 1403 Class::Handle(LookupCoreClass(Symbols::InvocationMirror())); | 1427 Class::Handle(LookupCoreClass(Symbols::InvocationMirror())); |
| 1404 ASSERT(!mirror_class.IsNull()); | 1428 ASSERT(!mirror_class.IsNull()); |
| 1405 const Function& allocation_function = Function::ZoneHandle( | 1429 const Function& allocation_function = Function::ZoneHandle( |
| 1406 mirror_class.LookupStaticFunction( | 1430 mirror_class.LookupStaticFunction( |
| (...skipping 7269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8676 ASSERT(factory_type_args.Length() == 1); | 8700 ASSERT(factory_type_args.Length() == 1); |
| 8677 Type& factory_type = Type::Handle(Type::New( | 8701 Type& factory_type = Type::Handle(Type::New( |
| 8678 factory_class, factory_type_args, type_pos, Heap::kNew)); | 8702 factory_class, factory_type_args, type_pos, Heap::kNew)); |
| 8679 factory_type ^= ClassFinalizer::FinalizeType( | 8703 factory_type ^= ClassFinalizer::FinalizeType( |
| 8680 current_class(), factory_type, ClassFinalizer::kFinalize); | 8704 current_class(), factory_type, ClassFinalizer::kFinalize); |
| 8681 factory_type_args = factory_type.arguments(); | 8705 factory_type_args = factory_type.arguments(); |
| 8682 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 8706 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
| 8683 } | 8707 } |
| 8684 factory_type_args = factory_type_args.Canonicalize(); | 8708 factory_type_args = factory_type_args.Canonicalize(); |
| 8685 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 8709 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| 8686 ArrayNode* list = new ArrayNode(TokenPos(), type, element_list); | 8710 const LocalVariable& temp_local = *BuildArrayTempLocal(type_pos); |
| 8711 ArrayNode* list = new ArrayNode(TokenPos(), type, temp_local, element_list); | |
| 8687 factory_param->Add(list); | 8712 factory_param->Add(list); |
| 8688 return CreateConstructorCallNode(literal_pos, | 8713 return CreateConstructorCallNode(literal_pos, |
| 8689 factory_type_args, | 8714 factory_type_args, |
| 8690 factory_method, | 8715 factory_method, |
| 8691 factory_param); | 8716 factory_param); |
| 8692 } | 8717 } |
| 8693 } | 8718 } |
| 8694 | 8719 |
| 8695 | 8720 |
| 8696 ConstructorCallNode* Parser::CreateConstructorCallNode( | 8721 ConstructorCallNode* Parser::CreateConstructorCallNode( |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8766 } | 8791 } |
| 8767 if (is_const && !value_type.IsInstantiated()) { | 8792 if (is_const && !value_type.IsInstantiated()) { |
| 8768 ErrorMsg(type_pos, | 8793 ErrorMsg(type_pos, |
| 8769 "the type argument of a constant map literal cannot include " | 8794 "the type argument of a constant map literal cannot include " |
| 8770 "a type variable"); | 8795 "a type variable"); |
| 8771 } | 8796 } |
| 8772 } | 8797 } |
| 8773 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 8798 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
| 8774 map_type_arguments ^= map_type_arguments.Canonicalize(); | 8799 map_type_arguments ^= map_type_arguments.Canonicalize(); |
| 8775 | 8800 |
| 8776 // The kv_pair array is temporary and of element type dynamic. It is passed | |
| 8777 // to the factory to initialize a properly typed map. | |
| 8778 GrowableArray<AstNode*> kv_pairs_list; | 8801 GrowableArray<AstNode*> kv_pairs_list; |
| 8779 // Parse the map entries. Note: there may be an optional extra | 8802 // Parse the map entries. Note: there may be an optional extra |
| 8780 // comma after the last entry. | 8803 // comma after the last entry. |
| 8781 while (CurrentToken() != Token::kRBRACE) { | 8804 while (CurrentToken() != Token::kRBRACE) { |
| 8782 AstNode* key = NULL; | 8805 AstNode* key = NULL; |
| 8783 if (CurrentToken() == Token::kSTRING) { | 8806 if (CurrentToken() == Token::kSTRING) { |
| 8784 key = ParseStringLiteral(); | 8807 key = ParseStringLiteral(); |
| 8785 } | 8808 } |
| 8786 if (key == NULL) { | 8809 if (key == NULL) { |
| 8787 ErrorMsg("map entry key must be string literal"); | 8810 ErrorMsg("map entry key must be string literal"); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8895 ASSERT(factory_type_args.Length() == 2); | 8918 ASSERT(factory_type_args.Length() == 2); |
| 8896 Type& factory_type = Type::Handle(Type::New( | 8919 Type& factory_type = Type::Handle(Type::New( |
| 8897 factory_class, factory_type_args, type_pos, Heap::kNew)); | 8920 factory_class, factory_type_args, type_pos, Heap::kNew)); |
| 8898 factory_type ^= ClassFinalizer::FinalizeType( | 8921 factory_type ^= ClassFinalizer::FinalizeType( |
| 8899 current_class(), factory_type, ClassFinalizer::kFinalize); | 8922 current_class(), factory_type, ClassFinalizer::kFinalize); |
| 8900 factory_type_args = factory_type.arguments(); | 8923 factory_type_args = factory_type.arguments(); |
| 8901 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 8924 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
| 8902 } | 8925 } |
| 8903 factory_type_args = factory_type_args.Canonicalize(); | 8926 factory_type_args = factory_type_args.Canonicalize(); |
| 8904 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 8927 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| 8928 // The kv_pair array is temporary and of element type dynamic. It is passed | |
| 8929 // to the factory to initialize a properly typed map. | |
| 8905 ArrayNode* kv_pairs = new ArrayNode( | 8930 ArrayNode* kv_pairs = new ArrayNode( |
| 8906 TokenPos(), Type::ZoneHandle(Type::ArrayType()), kv_pairs_list); | 8931 TokenPos(), |
| 8932 Type::ZoneHandle(Type::ArrayType()), | |
| 8933 *BuildArrayTempLocal(type_pos), | |
| 8934 kv_pairs_list); | |
| 8907 factory_param->Add(kv_pairs); | 8935 factory_param->Add(kv_pairs); |
| 8908 return CreateConstructorCallNode(literal_pos, | 8936 return CreateConstructorCallNode(literal_pos, |
| 8909 factory_type_args, | 8937 factory_type_args, |
| 8910 factory_method, | 8938 factory_method, |
| 8911 factory_param); | 8939 factory_param); |
| 8912 } | 8940 } |
| 8913 } | 8941 } |
| 8914 | 8942 |
| 8915 | 8943 |
| 8916 AstNode* Parser::ParseCompoundLiteral() { | 8944 AstNode* Parser::ParseCompoundLiteral() { |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9272 } | 9300 } |
| 9273 } | 9301 } |
| 9274 values_list.Add(expr); | 9302 values_list.Add(expr); |
| 9275 } | 9303 } |
| 9276 } | 9304 } |
| 9277 if (is_compiletime_const) { | 9305 if (is_compiletime_const) { |
| 9278 primary = new LiteralNode(literal_start, Interpolate(values_list)); | 9306 primary = new LiteralNode(literal_start, Interpolate(values_list)); |
| 9279 } else { | 9307 } else { |
| 9280 ArgumentListNode* interpolate_arg = new ArgumentListNode(TokenPos()); | 9308 ArgumentListNode* interpolate_arg = new ArgumentListNode(TokenPos()); |
| 9281 ArrayNode* values = new ArrayNode( | 9309 ArrayNode* values = new ArrayNode( |
| 9282 TokenPos(), Type::ZoneHandle(Type::ArrayType()), values_list); | 9310 TokenPos(), |
| 9311 Type::ZoneHandle(Type::ArrayType()), | |
| 9312 *BuildArrayTempLocal(TokenPos()), | |
| 9313 values_list); | |
| 9283 interpolate_arg->Add(values); | 9314 interpolate_arg->Add(values); |
| 9284 primary = MakeStaticCall(Symbols::StringBase(), | 9315 primary = MakeStaticCall(Symbols::StringBase(), |
| 9285 PrivateCoreLibName(Symbols::Interpolate()), | 9316 PrivateCoreLibName(Symbols::Interpolate()), |
| 9286 interpolate_arg); | 9317 interpolate_arg); |
| 9287 } | 9318 } |
| 9288 return primary; | 9319 return primary; |
| 9289 } | 9320 } |
| 9290 | 9321 |
| 9291 | 9322 |
| 9292 AstNode* Parser::ParseArgumentDefinitionTest() { | 9323 AstNode* Parser::ParseArgumentDefinitionTest() { |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9778 void Parser::SkipQualIdent() { | 9809 void Parser::SkipQualIdent() { |
| 9779 ASSERT(IsIdentifier()); | 9810 ASSERT(IsIdentifier()); |
| 9780 ConsumeToken(); | 9811 ConsumeToken(); |
| 9781 if (CurrentToken() == Token::kPERIOD) { | 9812 if (CurrentToken() == Token::kPERIOD) { |
| 9782 ConsumeToken(); // Consume the kPERIOD token. | 9813 ConsumeToken(); // Consume the kPERIOD token. |
| 9783 ExpectIdentifier("identifier expected after '.'"); | 9814 ExpectIdentifier("identifier expected after '.'"); |
| 9784 } | 9815 } |
| 9785 } | 9816 } |
| 9786 | 9817 |
| 9787 } // namespace dart | 9818 } // namespace dart |
| OLD | NEW |