| 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 "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 case RawFunction::kRegularFunction: | 803 case RawFunction::kRegularFunction: |
| 804 case RawFunction::kClosureFunction: | 804 case RawFunction::kClosureFunction: |
| 805 case RawFunction::kGetterFunction: | 805 case RawFunction::kGetterFunction: |
| 806 case RawFunction::kSetterFunction: | 806 case RawFunction::kSetterFunction: |
| 807 case RawFunction::kConstructor: | 807 case RawFunction::kConstructor: |
| 808 // The call to a redirecting factory is redirected. | 808 // The call to a redirecting factory is redirected. |
| 809 ASSERT(!func.IsRedirectingFactory()); | 809 ASSERT(!func.IsRedirectingFactory()); |
| 810 if (!func.IsImplicitConstructor()) { | 810 if (!func.IsImplicitConstructor()) { |
| 811 parser.SkipFunctionPreamble(); | 811 parser.SkipFunctionPreamble(); |
| 812 } | 812 } |
| 813 node_sequence = parser.ParseFunc(func, default_parameter_values); | 813 node_sequence = parser.ParseFunc(func, &default_parameter_values); |
| 814 break; | 814 break; |
| 815 case RawFunction::kImplicitGetter: | 815 case RawFunction::kImplicitGetter: |
| 816 ASSERT(!func.is_static()); | 816 ASSERT(!func.is_static()); |
| 817 node_sequence = parser.ParseInstanceGetter(func); | 817 node_sequence = parser.ParseInstanceGetter(func); |
| 818 break; | 818 break; |
| 819 case RawFunction::kImplicitSetter: | 819 case RawFunction::kImplicitSetter: |
| 820 ASSERT(!func.is_static()); | 820 ASSERT(!func.is_static()); |
| 821 node_sequence = parser.ParseInstanceSetter(func); | 821 node_sequence = parser.ParseInstanceSetter(func); |
| 822 break; | 822 break; |
| 823 case RawFunction::kImplicitStaticFinalGetter: | 823 case RawFunction::kImplicitStaticFinalGetter: |
| 824 node_sequence = parser.ParseStaticFinalGetter(func); | 824 node_sequence = parser.ParseStaticFinalGetter(func); |
| 825 CompilerStats::num_implicit_final_getters++; | 825 CompilerStats::num_implicit_final_getters++; |
| 826 break; | 826 break; |
| 827 case RawFunction::kStaticInitializer: | 827 case RawFunction::kStaticInitializer: |
| 828 node_sequence = parser.ParseStaticInitializer(func); | 828 node_sequence = parser.ParseStaticInitializer(func); |
| 829 CompilerStats::num_static_initializer_funcs++; | 829 CompilerStats::num_static_initializer_funcs++; |
| 830 break; | 830 break; |
| 831 case RawFunction::kMethodExtractor: | 831 case RawFunction::kMethodExtractor: |
| 832 node_sequence = parser.ParseMethodExtractor(func); | 832 node_sequence = parser.ParseMethodExtractor(func); |
| 833 break; | 833 break; |
| 834 case RawFunction::kNoSuchMethodDispatcher: | 834 case RawFunction::kNoSuchMethodDispatcher: |
| 835 node_sequence = | 835 node_sequence = |
| 836 parser.ParseNoSuchMethodDispatcher(func, default_parameter_values); | 836 parser.ParseNoSuchMethodDispatcher(func, &default_parameter_values); |
| 837 break; | 837 break; |
| 838 case RawFunction::kInvokeFieldDispatcher: | 838 case RawFunction::kInvokeFieldDispatcher: |
| 839 node_sequence = | 839 node_sequence = |
| 840 parser.ParseInvokeFieldDispatcher(func, default_parameter_values); | 840 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values); |
| 841 break; | 841 break; |
| 842 default: | 842 default: |
| 843 UNREACHABLE(); | 843 UNREACHABLE(); |
| 844 } | 844 } |
| 845 | 845 |
| 846 if (!HasReturnNode(node_sequence)) { | 846 if (!HasReturnNode(node_sequence)) { |
| 847 // Add implicit return node. | 847 // Add implicit return node. |
| 848 node_sequence->Add(new ReturnNode(func.end_token_pos())); | 848 node_sequence->Add(new ReturnNode(func.end_token_pos())); |
| 849 } | 849 } |
| 850 if (parsed_function->has_expression_temp_var()) { | 850 if (parsed_function->has_expression_temp_var()) { |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 NULL); | 1294 NULL); |
| 1295 | 1295 |
| 1296 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure); | 1296 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure); |
| 1297 current_block_->statements->Add(return_node); | 1297 current_block_->statements->Add(return_node); |
| 1298 return CloseBlock(); | 1298 return CloseBlock(); |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 | 1301 |
| 1302 void Parser::BuildDispatcherScope(const Function& func, | 1302 void Parser::BuildDispatcherScope(const Function& func, |
| 1303 const ArgumentsDescriptor& desc, | 1303 const ArgumentsDescriptor& desc, |
| 1304 Array& default_values) { | 1304 Array* default_values) { |
| 1305 ParamList params; | 1305 ParamList params; |
| 1306 // Receiver first. | 1306 // Receiver first. |
| 1307 intptr_t token_pos = func.token_pos(); | 1307 intptr_t token_pos = func.token_pos(); |
| 1308 params.AddReceiver(ReceiverType(current_class()), token_pos); | 1308 params.AddReceiver(ReceiverType(current_class()), token_pos); |
| 1309 // Remaining positional parameters. | 1309 // Remaining positional parameters. |
| 1310 intptr_t i = 1; | 1310 intptr_t i = 1; |
| 1311 for (; i < desc.PositionalCount(); ++i) { | 1311 for (; i < desc.PositionalCount(); ++i) { |
| 1312 ParamDesc p; | 1312 ParamDesc p; |
| 1313 char name[64]; | 1313 char name[64]; |
| 1314 OS::SNPrint(name, 64, ":p%" Pd, i); | 1314 OS::SNPrint(name, 64, ":p%" Pd, i); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1333 ASSERT(desc.NamedCount() == params.num_optional_parameters); | 1333 ASSERT(desc.NamedCount() == params.num_optional_parameters); |
| 1334 | 1334 |
| 1335 SetupDefaultsForOptionalParams(¶ms, default_values); | 1335 SetupDefaultsForOptionalParams(¶ms, default_values); |
| 1336 | 1336 |
| 1337 // Build local scope for function and populate with the formal parameters. | 1337 // Build local scope for function and populate with the formal parameters. |
| 1338 OpenFunctionBlock(func); | 1338 OpenFunctionBlock(func); |
| 1339 AddFormalParamsToScope(¶ms, current_block_->scope); | 1339 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1340 } | 1340 } |
| 1341 | 1341 |
| 1342 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, | 1342 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, |
| 1343 Array& default_values) { | 1343 Array* default_values) { |
| 1344 TRACE_PARSER("ParseNoSuchMethodDispatcher"); | 1344 TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
| 1345 | 1345 |
| 1346 ASSERT(func.IsNoSuchMethodDispatcher()); | 1346 ASSERT(func.IsNoSuchMethodDispatcher()); |
| 1347 intptr_t token_pos = func.token_pos(); | 1347 intptr_t token_pos = func.token_pos(); |
| 1348 ASSERT(func.token_pos() == 0); | 1348 ASSERT(func.token_pos() == 0); |
| 1349 ASSERT(current_class().raw() == func.Owner()); | 1349 ASSERT(current_class().raw() == func.Owner()); |
| 1350 | 1350 |
| 1351 ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc())); | 1351 ArgumentsDescriptor desc(Array::Handle(func.saved_args_desc())); |
| 1352 ASSERT(desc.Count() > 0); | 1352 ASSERT(desc.Count() > 0); |
| 1353 | 1353 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1378 StaticCallNode* call = | 1378 StaticCallNode* call = |
| 1379 new StaticCallNode(token_pos, no_such_method, arguments); | 1379 new StaticCallNode(token_pos, no_such_method, arguments); |
| 1380 | 1380 |
| 1381 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1381 ReturnNode* return_node = new ReturnNode(token_pos, call); |
| 1382 current_block_->statements->Add(return_node); | 1382 current_block_->statements->Add(return_node); |
| 1383 return CloseBlock(); | 1383 return CloseBlock(); |
| 1384 } | 1384 } |
| 1385 | 1385 |
| 1386 | 1386 |
| 1387 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, | 1387 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, |
| 1388 Array& default_values) { | 1388 Array* default_values) { |
| 1389 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1389 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
| 1390 | 1390 |
| 1391 ASSERT(func.IsInvokeFieldDispatcher()); | 1391 ASSERT(func.IsInvokeFieldDispatcher()); |
| 1392 intptr_t token_pos = func.token_pos(); | 1392 intptr_t token_pos = func.token_pos(); |
| 1393 ASSERT(func.token_pos() == 0); | 1393 ASSERT(func.token_pos() == 0); |
| 1394 ASSERT(current_class().raw() == func.Owner()); | 1394 ASSERT(current_class().raw() == func.Owner()); |
| 1395 | 1395 |
| 1396 const Array& args_desc = Array::Handle(func.saved_args_desc()); | 1396 const Array& args_desc = Array::Handle(func.saved_args_desc()); |
| 1397 ArgumentsDescriptor desc(args_desc); | 1397 ArgumentsDescriptor desc(args_desc); |
| 1398 ASSERT(desc.Count() > 0); | 1398 ASSERT(desc.Count() > 0); |
| (...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2554 } | 2554 } |
| 2555 ASSERT(!unregister_pending_function_); | 2555 ASSERT(!unregister_pending_function_); |
| 2556 pending_functions.Add(current_function()); | 2556 pending_functions.Add(current_function()); |
| 2557 unregister_pending_function_ = true; | 2557 unregister_pending_function_ = true; |
| 2558 } | 2558 } |
| 2559 | 2559 |
| 2560 | 2560 |
| 2561 // Parser is at the opening parenthesis of the formal parameter declaration | 2561 // Parser is at the opening parenthesis of the formal parameter declaration |
| 2562 // of function. Parse the formal parameters, initializers and code. | 2562 // of function. Parse the formal parameters, initializers and code. |
| 2563 SequenceNode* Parser::ParseConstructor(const Function& func, | 2563 SequenceNode* Parser::ParseConstructor(const Function& func, |
| 2564 Array& default_parameter_values) { | 2564 Array* default_parameter_values) { |
| 2565 TRACE_PARSER("ParseConstructor"); | 2565 TRACE_PARSER("ParseConstructor"); |
| 2566 ASSERT(func.IsConstructor()); | 2566 ASSERT(func.IsConstructor()); |
| 2567 ASSERT(!func.IsFactory()); | 2567 ASSERT(!func.IsFactory()); |
| 2568 ASSERT(!func.is_static()); | 2568 ASSERT(!func.is_static()); |
| 2569 ASSERT(!func.IsLocalFunction()); | 2569 ASSERT(!func.IsLocalFunction()); |
| 2570 const Class& cls = Class::Handle(func.Owner()); | 2570 const Class& cls = Class::Handle(func.Owner()); |
| 2571 ASSERT(!cls.IsNull()); | 2571 ASSERT(!cls.IsNull()); |
| 2572 | 2572 |
| 2573 CheckRecursiveInvocation(); | 2573 CheckRecursiveInvocation(); |
| 2574 | 2574 |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2846 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); | 2846 current_block_->statements->Add(new ReturnNode(func.end_token_pos())); |
| 2847 SequenceNode* statements = CloseBlock(); | 2847 SequenceNode* statements = CloseBlock(); |
| 2848 return statements; | 2848 return statements; |
| 2849 } | 2849 } |
| 2850 | 2850 |
| 2851 | 2851 |
| 2852 // Parser is at the opening parenthesis of the formal parameter | 2852 // Parser is at the opening parenthesis of the formal parameter |
| 2853 // declaration of the function or constructor. | 2853 // declaration of the function or constructor. |
| 2854 // Parse the formal parameters and code. | 2854 // Parse the formal parameters and code. |
| 2855 SequenceNode* Parser::ParseFunc(const Function& func, | 2855 SequenceNode* Parser::ParseFunc(const Function& func, |
| 2856 Array& default_parameter_values) { | 2856 Array* default_parameter_values) { |
| 2857 TRACE_PARSER("ParseFunc"); | 2857 TRACE_PARSER("ParseFunc"); |
| 2858 Function& saved_innermost_function = | 2858 Function& saved_innermost_function = |
| 2859 Function::Handle(innermost_function().raw()); | 2859 Function::Handle(innermost_function().raw()); |
| 2860 innermost_function_ = func.raw(); | 2860 innermost_function_ = func.raw(); |
| 2861 | 2861 |
| 2862 // Save current try index. Try index starts at zero for each function. | 2862 // Save current try index. Try index starts at zero for each function. |
| 2863 intptr_t saved_try_index = last_used_try_index_; | 2863 intptr_t saved_try_index = last_used_try_index_; |
| 2864 last_used_try_index_ = 0; | 2864 last_used_try_index_ = 0; |
| 2865 | 2865 |
| 2866 // TODO(12455) : Need better validation mechanism. | 2866 // TODO(12455) : Need better validation mechanism. |
| (...skipping 2458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5325 current_block_->scope->set_begin_token_pos(statements->token_pos()); | 5325 current_block_->scope->set_begin_token_pos(statements->token_pos()); |
| 5326 current_block_->scope->set_end_token_pos(TokenPos()); | 5326 current_block_->scope->set_end_token_pos(TokenPos()); |
| 5327 } | 5327 } |
| 5328 current_block_ = current_block_->parent; | 5328 current_block_ = current_block_->parent; |
| 5329 return statements; | 5329 return statements; |
| 5330 } | 5330 } |
| 5331 | 5331 |
| 5332 | 5332 |
| 5333 // Set up default values for all optional parameters to the function. | 5333 // Set up default values for all optional parameters to the function. |
| 5334 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 5334 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
| 5335 Array& default_values) { | 5335 Array* default_values) { |
| 5336 if (params->num_optional_parameters > 0) { | 5336 if (params->num_optional_parameters > 0) { |
| 5337 // Build array of default parameter values. | 5337 // Build array of default parameter values. |
| 5338 ParamDesc* param = | 5338 ParamDesc* param = |
| 5339 params->parameters->data() + params->num_fixed_parameters; | 5339 params->parameters->data() + params->num_fixed_parameters; |
| 5340 default_values = Array::New(params->num_optional_parameters); | 5340 *default_values = Array::New(params->num_optional_parameters); |
| 5341 for (int i = 0; i < params->num_optional_parameters; i++) { | 5341 for (int i = 0; i < params->num_optional_parameters; i++) { |
| 5342 ASSERT(param->default_value != NULL); | 5342 ASSERT(param->default_value != NULL); |
| 5343 default_values.SetAt(i, *param->default_value); | 5343 default_values->SetAt(i, *param->default_value); |
| 5344 param++; | 5344 param++; |
| 5345 } | 5345 } |
| 5346 } | 5346 } |
| 5347 } | 5347 } |
| 5348 | 5348 |
| 5349 | 5349 |
| 5350 // Populate the parameter type array and parameter name array of the function | 5350 // Populate the parameter type array and parameter name array of the function |
| 5351 // with the formal parameter types and names. | 5351 // with the formal parameter types and names. |
| 5352 void Parser::AddFormalParamsToFunction(const ParamList* params, | 5352 void Parser::AddFormalParamsToFunction(const ParamList* params, |
| 5353 const Function& func) { | 5353 const Function& func) { |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5759 ErrorMsg(function_pos, | 5759 ErrorMsg(function_pos, |
| 5760 "'%s' from outer scope has already been used, cannot redefine", | 5760 "'%s' from outer scope has already been used, cannot redefine", |
| 5761 function_variable->name().ToCString()); | 5761 function_variable->name().ToCString()); |
| 5762 } | 5762 } |
| 5763 } | 5763 } |
| 5764 } | 5764 } |
| 5765 | 5765 |
| 5766 // Parse the local function. | 5766 // Parse the local function. |
| 5767 Array& default_parameter_values = Array::Handle(); | 5767 Array& default_parameter_values = Array::Handle(); |
| 5768 SequenceNode* statements = Parser::ParseFunc(function, | 5768 SequenceNode* statements = Parser::ParseFunc(function, |
| 5769 default_parameter_values); | 5769 &default_parameter_values); |
| 5770 | 5770 |
| 5771 // Now that the local function has formal parameters, lookup the signature | 5771 // Now that the local function has formal parameters, lookup the signature |
| 5772 // class in the current library (but not in its imports) and only create a new | 5772 // class in the current library (but not in its imports) and only create a new |
| 5773 // canonical signature class if it does not exist yet. | 5773 // canonical signature class if it does not exist yet. |
| 5774 const String& signature = String::Handle(function.Signature()); | 5774 const String& signature = String::Handle(function.Signature()); |
| 5775 Class& signature_class = Class::ZoneHandle(); | 5775 Class& signature_class = Class::ZoneHandle(); |
| 5776 if (!is_new_closure) { | 5776 if (!is_new_closure) { |
| 5777 signature_class = function.signature_class(); | 5777 signature_class = function.signature_class(); |
| 5778 } | 5778 } |
| 5779 if (signature_class.IsNull()) { | 5779 if (signature_class.IsNull()) { |
| (...skipping 3210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8990 // not optimizable. | 8990 // not optimizable. |
| 8991 current_function().SetIsOptimizable(false); | 8991 current_function().SetIsOptimizable(false); |
| 8992 field.set_value(Object::null_instance()); | 8992 field.set_value(Object::null_instance()); |
| 8993 // It is a compile-time error if evaluation of a compile-time constant | 8993 // It is a compile-time error if evaluation of a compile-time constant |
| 8994 // would raise an exception. | 8994 // would raise an exception. |
| 8995 AppendErrorMsg(error, field_ref_pos, | 8995 AppendErrorMsg(error, field_ref_pos, |
| 8996 "error initializing const field '%s'", | 8996 "error initializing const field '%s'", |
| 8997 String::Handle(field.name()).ToCString()); | 8997 String::Handle(field.name()).ToCString()); |
| 8998 } else { | 8998 } else { |
| 8999 isolate()->long_jump_base()->Jump(1, error); | 8999 isolate()->long_jump_base()->Jump(1, error); |
| 9000 UNREACHABLE(); |
| 9000 } | 9001 } |
| 9001 } | 9002 } |
| 9002 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 9003 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 9003 Instance& instance = Instance::Handle(); | 9004 Instance& instance = Instance::Handle(); |
| 9004 instance ^= const_value.raw(); | 9005 instance ^= const_value.raw(); |
| 9005 instance = TryCanonicalize(instance, field_ref_pos); | 9006 instance = TryCanonicalize(instance, field_ref_pos); |
| 9006 field.set_value(instance); | 9007 field.set_value(instance); |
| 9007 return NULL; // Constant | 9008 return NULL; // Constant |
| 9008 } else { | 9009 } else { |
| 9009 return new StaticGetterNode(field_ref_pos, | 9010 return new StaticGetterNode(field_ref_pos, |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9486 ResolveTypeFromClass(current_class(), finalization, &type); | 9487 ResolveTypeFromClass(current_class(), finalization, &type); |
| 9487 if (finalization >= ClassFinalizer::kCanonicalize) { | 9488 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 9488 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 9489 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
| 9489 } | 9490 } |
| 9490 } | 9491 } |
| 9491 return type.raw(); | 9492 return type.raw(); |
| 9492 } | 9493 } |
| 9493 | 9494 |
| 9494 | 9495 |
| 9495 void Parser::CheckConstructorCallTypeArguments( | 9496 void Parser::CheckConstructorCallTypeArguments( |
| 9496 intptr_t pos, Function& constructor, | 9497 intptr_t pos, const Function& constructor, |
| 9497 const TypeArguments& type_arguments) { | 9498 const TypeArguments& type_arguments) { |
| 9498 if (!type_arguments.IsNull()) { | 9499 if (!type_arguments.IsNull()) { |
| 9499 const Class& constructor_class = Class::Handle(constructor.Owner()); | 9500 const Class& constructor_class = Class::Handle(constructor.Owner()); |
| 9500 ASSERT(!constructor_class.IsNull()); | 9501 ASSERT(!constructor_class.IsNull()); |
| 9501 ASSERT(constructor_class.is_finalized()); | 9502 ASSERT(constructor_class.is_finalized()); |
| 9502 ASSERT(type_arguments.IsCanonical()); | 9503 ASSERT(type_arguments.IsCanonical()); |
| 9503 // Do not report the expected vs. actual number of type arguments, because | 9504 // Do not report the expected vs. actual number of type arguments, because |
| 9504 // the type argument vector is flattened and raw types are allowed. | 9505 // the type argument vector is flattened and raw types are allowed. |
| 9505 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 9506 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
| 9506 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); | 9507 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); |
| (...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10285 for (int i = 0; i < values.length(); i++) { | 10286 for (int i = 0; i < values.length(); i++) { |
| 10286 ASSERT(values[i]->IsLiteralNode()); | 10287 ASSERT(values[i]->IsLiteralNode()); |
| 10287 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); | 10288 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); |
| 10288 } | 10289 } |
| 10289 | 10290 |
| 10290 // Build argument array to pass to the interpolation function. | 10291 // Build argument array to pass to the interpolation function. |
| 10291 const Array& interpolate_arg = Array::Handle(isolate(), Array::New(1)); | 10292 const Array& interpolate_arg = Array::Handle(isolate(), Array::New(1)); |
| 10292 interpolate_arg.SetAt(0, value_arr); | 10293 interpolate_arg.SetAt(0, value_arr); |
| 10293 | 10294 |
| 10294 // Call interpolation function. | 10295 // Call interpolation function. |
| 10295 String& concatenated = String::ZoneHandle(isolate()); | 10296 Object& result = Object::Handle(isolate()); |
| 10296 { | 10297 { |
| 10297 PAUSETIMERSCOPE(isolate(), time_compilation); | 10298 PAUSETIMERSCOPE(isolate(), time_compilation); |
| 10298 concatenated ^= DartEntry::InvokeFunction(func, interpolate_arg); | 10299 result = DartEntry::InvokeFunction(func, interpolate_arg); |
| 10299 } | 10300 } |
| 10300 if (concatenated.IsUnhandledException()) { | 10301 if (result.IsUnhandledException()) { |
| 10301 ErrorMsg("Exception thrown in Parser::Interpolate"); | 10302 ErrorMsg("%s", Error::Cast(result).ToErrorCString()); |
| 10302 } | 10303 } |
| 10304 String& concatenated = String::ZoneHandle(isolate()); |
| 10305 concatenated ^= result.raw(); |
| 10303 concatenated = Symbols::New(concatenated); | 10306 concatenated = Symbols::New(concatenated); |
| 10304 return concatenated; | 10307 return concatenated; |
| 10305 } | 10308 } |
| 10306 | 10309 |
| 10307 | 10310 |
| 10308 // A string literal consists of the concatenation of the next n tokens | 10311 // A string literal consists of the concatenation of the next n tokens |
| 10309 // that satisfy the EBNF grammar: | 10312 // that satisfy the EBNF grammar: |
| 10310 // literal = kSTRING {{ interpol } kSTRING } | 10313 // literal = kSTRING {{ interpol } kSTRING } |
| 10311 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 10314 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 10312 // In other words, the scanner breaks down interpolated strings so that | 10315 // In other words, the scanner breaks down interpolated strings so that |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10946 void Parser::SkipQualIdent() { | 10949 void Parser::SkipQualIdent() { |
| 10947 ASSERT(IsIdentifier()); | 10950 ASSERT(IsIdentifier()); |
| 10948 ConsumeToken(); | 10951 ConsumeToken(); |
| 10949 if (CurrentToken() == Token::kPERIOD) { | 10952 if (CurrentToken() == Token::kPERIOD) { |
| 10950 ConsumeToken(); // Consume the kPERIOD token. | 10953 ConsumeToken(); // Consume the kPERIOD token. |
| 10951 ExpectIdentifier("identifier expected after '.'"); | 10954 ExpectIdentifier("identifier expected after '.'"); |
| 10952 } | 10955 } |
| 10953 } | 10956 } |
| 10954 | 10957 |
| 10955 } // namespace dart | 10958 } // namespace dart |
| OLD | NEW |