Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 Array& a = Array::Handle(Array::New(objs.length(), Heap::kOld)); | 79 Array& a = Array::Handle(Array::New(objs.length(), Heap::kOld)); |
| 80 for (int i = 0; i < objs.length(); i++) { | 80 for (int i = 0; i < objs.length(); i++) { |
| 81 a.SetAt(i, *objs[i]); | 81 a.SetAt(i, *objs[i]); |
| 82 } | 82 } |
| 83 return a.raw(); | 83 return a.raw(); |
| 84 } | 84 } |
| 85 | 85 |
| 86 | 86 |
| 87 static RawTypeArguments* NewTypeArguments( | 87 static RawTypeArguments* NewTypeArguments( |
| 88 const GrowableArray<AbstractType*>& objs) { | 88 const GrowableArray<AbstractType*>& objs) { |
| 89 TypeArguments& a = TypeArguments::Handle(TypeArguments::New(objs.length())); | 89 const TypeArguments& a = |
| 90 TypeArguments::Handle(TypeArguments::New(objs.length())); | |
| 90 for (int i = 0; i < objs.length(); i++) { | 91 for (int i = 0; i < objs.length(); i++) { |
| 91 a.SetTypeAt(i, *objs[i]); | 92 a.SetTypeAt(i, *objs[i]); |
| 92 } | 93 } |
| 94 // Cannot canonicalize TypeArgument yet as its types may not have been | |
| 95 // finalized yet. | |
| 93 return a.raw(); | 96 return a.raw(); |
| 94 } | 97 } |
| 95 | 98 |
| 96 | 99 |
| 97 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos, | 100 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos, |
| 98 const Instance& instance) { | 101 const Instance& instance) { |
| 99 UnhandledException& excp = UnhandledException::Handle(); | 102 UnhandledException& excp = UnhandledException::Handle(); |
| 100 excp ^= instance.raw(); | 103 excp ^= instance.raw(); |
| 101 const Instance& exception = Instance::ZoneHandle(excp.exception()); | 104 const Instance& exception = Instance::ZoneHandle(excp.exception()); |
| 102 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); | 105 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); |
| (...skipping 6628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6731 literal_factory_class.LookupFactory(literal_list_factory_name)); | 6734 literal_factory_class.LookupFactory(literal_list_factory_name)); |
| 6732 ASSERT(!literal_list_factory.IsNull()); | 6735 ASSERT(!literal_list_factory.IsNull()); |
| 6733 if (!type_arguments.IsNull() && | 6736 if (!type_arguments.IsNull() && |
| 6734 !type_arguments.IsInstantiated() && | 6737 !type_arguments.IsInstantiated() && |
| 6735 (current_block_->scope->function_level() > 0)) { | 6738 (current_block_->scope->function_level() > 0)) { |
| 6736 // Make sure that the instantiator is captured. | 6739 // Make sure that the instantiator is captured. |
| 6737 CaptureReceiver(); | 6740 CaptureReceiver(); |
| 6738 } | 6741 } |
| 6739 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 6742 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| 6740 factory_param->Add(list); | 6743 factory_param->Add(list); |
| 6741 return new ConstructorCallNode( | 6744 AbstractTypeArguments& canonical_type_arguments = |
| 6742 literal_pos, type_arguments, literal_list_factory, factory_param); | 6745 AbstractTypeArguments::ZoneHandle(type_arguments.Canonicalize()); |
| 6746 return new ConstructorCallNode(literal_pos, | |
| 6747 canonical_type_arguments, | |
| 6748 literal_list_factory, | |
| 6749 factory_param); | |
| 6743 } | 6750 } |
| 6744 } | 6751 } |
| 6745 | 6752 |
| 6746 | 6753 |
| 6747 static void AddKeyValuePair(ArrayNode* pairs, | 6754 static void AddKeyValuePair(ArrayNode* pairs, |
| 6748 bool is_const, | 6755 bool is_const, |
| 6749 AstNode* key, | 6756 AstNode* key, |
| 6750 AstNode* value) { | 6757 AstNode* value) { |
| 6751 if (is_const) { | 6758 if (is_const) { |
| 6752 ASSERT(key->IsLiteralNode()); | 6759 ASSERT(key->IsLiteralNode()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6800 "the key type of a map literal is implicitly 'String'"); | 6807 "the key type of a map literal is implicitly 'String'"); |
| 6801 } | 6808 } |
| 6802 Warning(type_pos, | 6809 Warning(type_pos, |
| 6803 "a map literal takes one type argument specifying " | 6810 "a map literal takes one type argument specifying " |
| 6804 "the value type"); | 6811 "the value type"); |
| 6805 value_type = map_type_arguments.TypeAt(1); | 6812 value_type = map_type_arguments.TypeAt(1); |
| 6806 } else { | 6813 } else { |
| 6807 TypeArguments& type_array = TypeArguments::Handle(TypeArguments::New(2)); | 6814 TypeArguments& type_array = TypeArguments::Handle(TypeArguments::New(2)); |
| 6808 type_array.SetTypeAt(0, Type::Handle(Type::StringInterface())); | 6815 type_array.SetTypeAt(0, Type::Handle(Type::StringInterface())); |
| 6809 type_array.SetTypeAt(1, value_type); | 6816 type_array.SetTypeAt(1, value_type); |
| 6810 map_type_arguments = type_array.raw(); | 6817 map_type_arguments = type_array.Canonicalize(); |
|
regis
2011/12/05 23:16:35
Is this necessary? You canonicalize below as well.
srdjan
2011/12/06 17:24:15
Removed, doing it later
| |
| 6811 } | 6818 } |
| 6812 if (is_const && !value_type.IsInstantiated()) { | 6819 if (is_const && !value_type.IsInstantiated()) { |
| 6813 ErrorMsg(type_pos, | 6820 ErrorMsg(type_pos, |
| 6814 "the type argument of a constant map literal cannot include " | 6821 "the type argument of a constant map literal cannot include " |
| 6815 "a type variable"); | 6822 "a type variable"); |
| 6816 } | 6823 } |
| 6817 } | 6824 } |
| 6818 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 6825 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
|
srdjan
2011/12/06 17:24:15
Canonicalizing it here,
| |
| 6819 | 6826 |
| 6820 // Parse the map entries. Note: there may be an optional extra | 6827 // Parse the map entries. Note: there may be an optional extra |
| 6821 // comma after the last entry. | 6828 // comma after the last entry. |
| 6822 ArrayNode* kv_pairs = | 6829 ArrayNode* kv_pairs = |
| 6823 new ArrayNode(token_index_, TypeArguments::ZoneHandle()); | 6830 new ArrayNode(token_index_, TypeArguments::ZoneHandle()); |
| 6824 const String& dst_name = String::ZoneHandle( | 6831 const String& dst_name = String::ZoneHandle( |
| 6825 String::NewSymbol("list literal element")); | 6832 String::NewSymbol("list literal element")); |
| 6826 while (CurrentToken() != Token::kRBRACE) { | 6833 while (CurrentToken() != Token::kRBRACE) { |
| 6827 AstNode* key = NULL; | 6834 AstNode* key = NULL; |
| 6828 if (CurrentToken() == Token::kSTRING) { | 6835 if (CurrentToken() == Token::kSTRING) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6901 ASSERT(!immutable_map_class.IsNull()); | 6908 ASSERT(!immutable_map_class.IsNull()); |
| 6902 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); | 6909 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); |
| 6903 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); | 6910 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); |
| 6904 const String& constr_name = | 6911 const String& constr_name = |
| 6905 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); | 6912 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); |
| 6906 const Function& map_constr = Function::ZoneHandle( | 6913 const Function& map_constr = Function::ZoneHandle( |
| 6907 immutable_map_class.LookupConstructor(constr_name)); | 6914 immutable_map_class.LookupConstructor(constr_name)); |
| 6908 ASSERT(!map_constr.IsNull()); | 6915 ASSERT(!map_constr.IsNull()); |
| 6909 const Instance& const_instance = Instance::ZoneHandle( | 6916 const Instance& const_instance = Instance::ZoneHandle( |
| 6910 EvaluateConstConstructorCall(immutable_map_class, | 6917 EvaluateConstConstructorCall(immutable_map_class, |
| 6911 map_type_arguments, | 6918 map_type_arguments, |
|
regis
2011/12/05 23:16:35
Why not canonicalize here as well?
srdjan
2011/12/06 17:24:15
Done it above
| |
| 6912 map_constr, | 6919 map_constr, |
| 6913 constr_args)); | 6920 constr_args)); |
| 6914 if (const_instance.IsUnhandledException()) { | 6921 if (const_instance.IsUnhandledException()) { |
| 6915 return CreateEvalConstConstructorThrow(literal_pos, const_instance); | 6922 return CreateEvalConstConstructorThrow(literal_pos, const_instance); |
| 6916 } else { | 6923 } else { |
| 6917 return new LiteralNode(literal_pos, const_instance); | 6924 return new LiteralNode(literal_pos, const_instance); |
| 6918 } | 6925 } |
| 6919 } else { | 6926 } else { |
| 6920 // Factory call at runtime. | 6927 // Factory call at runtime. |
| 6921 String& literal_factory_class_name = String::Handle( | 6928 String& literal_factory_class_name = String::Handle( |
| 6922 String::NewSymbol(kLiteralFactoryClassName)); | 6929 String::NewSymbol(kLiteralFactoryClassName)); |
| 6923 const Class& literal_factory_class = | 6930 const Class& literal_factory_class = |
| 6924 Class::Handle(LookupCoreClass(literal_factory_class_name)); | 6931 Class::Handle(LookupCoreClass(literal_factory_class_name)); |
| 6925 ASSERT(!literal_factory_class.IsNull()); | 6932 ASSERT(!literal_factory_class.IsNull()); |
| 6926 const String& literal_map_factory_name = | 6933 const String& literal_map_factory_name = |
| 6927 String::Handle(String::NewSymbol(kLiteralFactoryMapFromLiteralName)); | 6934 String::Handle(String::NewSymbol(kLiteralFactoryMapFromLiteralName)); |
| 6928 const Function& literal_map_factory = Function::ZoneHandle( | 6935 const Function& literal_map_factory = Function::ZoneHandle( |
| 6929 literal_factory_class.LookupFactory(literal_map_factory_name)); | 6936 literal_factory_class.LookupFactory(literal_map_factory_name)); |
| 6930 ASSERT(!literal_map_factory.IsNull()); | 6937 ASSERT(!literal_map_factory.IsNull()); |
| 6931 if (!map_type_arguments.IsNull() && | 6938 if (!map_type_arguments.IsNull() && |
| 6932 !map_type_arguments.IsInstantiated() && | 6939 !map_type_arguments.IsInstantiated() && |
| 6933 (current_block_->scope->function_level() > 0)) { | 6940 (current_block_->scope->function_level() > 0)) { |
| 6934 // Make sure that the instantiator is captured. | 6941 // Make sure that the instantiator is captured. |
| 6935 CaptureReceiver(); | 6942 CaptureReceiver(); |
| 6936 } | 6943 } |
| 6937 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); | 6944 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); |
| 6938 factory_param->Add(kv_pairs); | 6945 factory_param->Add(kv_pairs); |
| 6939 return new ConstructorCallNode( | 6946 AbstractTypeArguments& canonical_map_type_arguments = |
| 6940 literal_pos, map_type_arguments, literal_map_factory, factory_param); | 6947 AbstractTypeArguments::ZoneHandle(map_type_arguments.Canonicalize()); |
|
srdjan
2011/12/06 17:24:15
Reverted this.
| |
| 6948 return new ConstructorCallNode(literal_pos, | |
| 6949 canonical_map_type_arguments, | |
| 6950 literal_map_factory, | |
| 6951 factory_param); | |
| 6941 } | 6952 } |
| 6942 } | 6953 } |
| 6943 | 6954 |
| 6944 | 6955 |
| 6945 AstNode* Parser::ParseCompoundLiteral() { | 6956 AstNode* Parser::ParseCompoundLiteral() { |
| 6946 bool is_const = false; | 6957 bool is_const = false; |
| 6947 if (CurrentToken() == Token::kCONST) { | 6958 if (CurrentToken() == Token::kCONST) { |
| 6948 is_const = true; | 6959 is_const = true; |
| 6949 ConsumeToken(); | 6960 ConsumeToken(); |
| 6950 } | 6961 } |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7146 | 7157 |
| 7147 // Make the constructor call. | 7158 // Make the constructor call. |
| 7148 AstNode* new_object = NULL; | 7159 AstNode* new_object = NULL; |
| 7149 if (is_const) { | 7160 if (is_const) { |
| 7150 if (!constructor.is_const()) { | 7161 if (!constructor.is_const()) { |
| 7151 ErrorMsg("'const' requires const constructor: '%s'", | 7162 ErrorMsg("'const' requires const constructor: '%s'", |
| 7152 String::Handle(constructor.name()).ToCString()); | 7163 String::Handle(constructor.name()).ToCString()); |
| 7153 } | 7164 } |
| 7154 const Instance& const_instance = Instance::ZoneHandle( | 7165 const Instance& const_instance = Instance::ZoneHandle( |
| 7155 EvaluateConstConstructorCall(type_class, | 7166 EvaluateConstConstructorCall(type_class, |
| 7156 type_arguments, | 7167 type_arguments, |
|
regis
2011/12/05 23:16:35
ditto
srdjan
2011/12/06 17:24:15
Done by moving canonicalization before if (is_cons
| |
| 7157 constructor, | 7168 constructor, |
| 7158 arguments)); | 7169 arguments)); |
| 7159 if (const_instance.IsUnhandledException()) { | 7170 if (const_instance.IsUnhandledException()) { |
| 7160 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance); | 7171 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance); |
| 7161 } else { | 7172 } else { |
| 7162 new_object = new LiteralNode(new_pos, const_instance); | 7173 new_object = new LiteralNode(new_pos, const_instance); |
| 7163 } | 7174 } |
| 7164 } else { | 7175 } else { |
| 7165 CheckFunctionIsCallable(new_pos, constructor); | 7176 CheckFunctionIsCallable(new_pos, constructor); |
| 7166 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 7177 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 7167 if (!type_arguments.IsNull() && | 7178 if (!type_arguments.IsNull() && |
| 7168 !type_arguments.IsInstantiated() && | 7179 !type_arguments.IsInstantiated() && |
| 7169 (current_block_->scope->function_level() > 0)) { | 7180 (current_block_->scope->function_level() > 0)) { |
| 7170 // Make sure that the instantiator is captured. | 7181 // Make sure that the instantiator is captured. |
| 7171 CaptureReceiver(); | 7182 CaptureReceiver(); |
| 7172 } | 7183 } |
| 7184 AbstractTypeArguments& canonical_type_arguments = | |
| 7185 AbstractTypeArguments::ZoneHandle(type_arguments.Canonicalize()); | |
| 7173 new_object = new ConstructorCallNode( | 7186 new_object = new ConstructorCallNode( |
| 7174 new_pos, type_arguments, constructor, arguments); | 7187 new_pos, canonical_type_arguments, constructor, arguments); |
| 7175 } | 7188 } |
| 7176 return new_object; | 7189 return new_object; |
| 7177 } | 7190 } |
| 7178 | 7191 |
| 7179 | 7192 |
| 7180 // A string literal consists of the concatenation of the next n tokens | 7193 // A string literal consists of the concatenation of the next n tokens |
| 7181 // that satisfy the EBNF grammar: | 7194 // that satisfy the EBNF grammar: |
| 7182 // literal = kSTRING {{ interpol }+ kSTRING } | 7195 // literal = kSTRING {{ interpol }+ kSTRING } |
| 7183 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 7196 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 7184 // In other words, the scanner breaks down interpolated strings so that | 7197 // In other words, the scanner breaks down interpolated strings so that |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7607 } | 7620 } |
| 7608 | 7621 |
| 7609 | 7622 |
| 7610 void Parser::SkipNestedExpr() { | 7623 void Parser::SkipNestedExpr() { |
| 7611 const bool saved_mode = SetAllowFunctionLiterals(true); | 7624 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7612 SkipExpr(); | 7625 SkipExpr(); |
| 7613 SetAllowFunctionLiterals(saved_mode); | 7626 SetAllowFunctionLiterals(saved_mode); |
| 7614 } | 7627 } |
| 7615 | 7628 |
| 7616 } // namespace dart | 7629 } // namespace dart |
| OLD | NEW |