Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: runtime/vm/parser.cc

Issue 15979010: Fix two bugs in the Dart VM's super-noSuchMethod invocation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/unit_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); 102 Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace());
103 if (stack_trace.IsNew()) { 103 if (stack_trace.IsNew()) {
104 stack_trace ^= Object::Clone(stack_trace, Heap::kOld); 104 stack_trace ^= Object::Clone(stack_trace, Heap::kOld);
105 } 105 }
106 return new ThrowNode(token_pos, 106 return new ThrowNode(token_pos,
107 new LiteralNode(token_pos, exception), 107 new LiteralNode(token_pos, exception),
108 new LiteralNode(token_pos, stack_trace)); 108 new LiteralNode(token_pos, stack_trace));
109 } 109 }
110 110
111 111
112 LocalVariable* ParsedFunction::CreateExpressionTempVar(intptr_t token_pos) { 112 LocalVariable* ParsedFunction::EnsureExpressionTemp() {
113 return new LocalVariable(token_pos, 113 if (!has_expression_temp_var()) {
114 Symbols::ExprTemp(), 114 LocalVariable* temp =
115 Type::ZoneHandle(Type::DynamicType())); 115 new LocalVariable(function_.token_pos(),
116 Symbols::ExprTemp(),
117 Type::ZoneHandle(Type::DynamicType()));
118 ASSERT(temp != NULL);
119 set_expression_temp_var(temp);
120 }
121 ASSERT(has_expression_temp_var());
122 return expression_temp_var();
116 } 123 }
117 124
118 125
119 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { 126 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) {
120 ASSERT(node_sequence_ == NULL); 127 ASSERT(node_sequence_ == NULL);
121 ASSERT(node_sequence != NULL); 128 ASSERT(node_sequence != NULL);
122 node_sequence_ = node_sequence; 129 node_sequence_ = node_sequence;
123 } 130 }
124 131
125 132
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 static const String& PrivateCoreLibName(const String& str) { 1401 static const String& PrivateCoreLibName(const String& str) {
1395 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 1402 const Library& core_lib = Library::Handle(Library::CoreLibrary());
1396 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); 1403 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str));
1397 return private_name; 1404 return private_name;
1398 } 1405 }
1399 1406
1400 1407
1401 StaticCallNode* Parser::BuildInvocationMirrorAllocation( 1408 StaticCallNode* Parser::BuildInvocationMirrorAllocation(
1402 intptr_t call_pos, 1409 intptr_t call_pos,
1403 const String& function_name, 1410 const String& function_name,
1404 const ArgumentListNode& function_args) { 1411 const ArgumentListNode& function_args,
1412 const LocalVariable* temp_for_last_arg) {
1405 const intptr_t args_pos = function_args.token_pos(); 1413 const intptr_t args_pos = function_args.token_pos();
1406 // Build arguments to the call to the static 1414 // Build arguments to the call to the static
1407 // InvocationMirror._allocateInvocationMirror method. 1415 // InvocationMirror._allocateInvocationMirror method.
1408 ArgumentListNode* arguments = new ArgumentListNode(args_pos); 1416 ArgumentListNode* arguments = new ArgumentListNode(args_pos);
1409 // The first argument is the original function name. 1417 // The first argument is the original function name.
1410 arguments->Add(new LiteralNode(args_pos, function_name)); 1418 arguments->Add(new LiteralNode(args_pos, function_name));
1411 // The second argument is the arguments descriptor of the original function. 1419 // The second argument is the arguments descriptor of the original function.
1412 const Array& args_descriptor = 1420 const Array& args_descriptor =
1413 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), 1421 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(),
1414 function_args.names())); 1422 function_args.names()));
1415 arguments->Add(new LiteralNode(args_pos, args_descriptor)); 1423 arguments->Add(new LiteralNode(args_pos, args_descriptor));
1416 // The third argument is an array containing the original function arguments, 1424 // The third argument is an array containing the original function arguments,
1417 // including the receiver. 1425 // including the receiver.
1418 ArrayNode* args_array = 1426 ArrayNode* args_array =
1419 new ArrayNode(args_pos, Type::ZoneHandle(Type::ArrayType())); 1427 new ArrayNode(args_pos, Type::ZoneHandle(Type::ArrayType()));
1420 for (intptr_t i = 0; i < function_args.length(); i++) { 1428 for (intptr_t i = 0; i < function_args.length(); i++) {
1421 args_array->AddElement(function_args.NodeAt(i)); 1429 AstNode* arg = function_args.NodeAt(i);
1430 if ((temp_for_last_arg != NULL) && (i == function_args.length() - 1)) {
1431 args_array->AddElement(
1432 new CommaNode(arg->token_pos(),
1433 new StoreLocalNode(arg->token_pos(),
1434 temp_for_last_arg,
1435 arg),
1436 new LoadLocalNode(arg->token_pos(),
1437 temp_for_last_arg)));
1438 } else {
1439 args_array->AddElement(function_args.NodeAt(i));
1440 }
1422 } 1441 }
1423 arguments->Add(args_array); 1442 arguments->Add(args_array);
1424 // Lookup the static InvocationMirror._allocateInvocationMirror method. 1443 // Lookup the static InvocationMirror._allocateInvocationMirror method.
1425 const Class& mirror_class = 1444 const Class& mirror_class =
1426 Class::Handle(LookupCoreClass(Symbols::InvocationMirror())); 1445 Class::Handle(LookupCoreClass(Symbols::InvocationMirror()));
1427 ASSERT(!mirror_class.IsNull()); 1446 ASSERT(!mirror_class.IsNull());
1428 const Function& allocation_function = Function::ZoneHandle( 1447 const Function& allocation_function = Function::ZoneHandle(
1429 mirror_class.LookupStaticFunction( 1448 mirror_class.LookupStaticFunction(
1430 PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); 1449 PrivateCoreLibName(Symbols::AllocateInvocationMirror())));
1431 ASSERT(!allocation_function.IsNull()); 1450 ASSERT(!allocation_function.IsNull());
1432 return new StaticCallNode(call_pos, allocation_function, arguments); 1451 return new StaticCallNode(call_pos, allocation_function, arguments);
1433 } 1452 }
1434 1453
1435 1454
1436 ArgumentListNode* Parser::BuildNoSuchMethodArguments( 1455 ArgumentListNode* Parser::BuildNoSuchMethodArguments(
1437 intptr_t call_pos, 1456 intptr_t call_pos,
1438 const String& function_name, 1457 const String& function_name,
1439 const ArgumentListNode& function_args) { 1458 const ArgumentListNode& function_args,
1459 const LocalVariable* temp_for_last_arg) {
1440 ASSERT(function_args.length() >= 1); // The receiver is the first argument. 1460 ASSERT(function_args.length() >= 1); // The receiver is the first argument.
1441 const intptr_t args_pos = function_args.token_pos(); 1461 const intptr_t args_pos = function_args.token_pos();
1442 ArgumentListNode* arguments = new ArgumentListNode(args_pos); 1462 ArgumentListNode* arguments = new ArgumentListNode(args_pos);
1443 arguments->Add(function_args.NodeAt(0)); 1463 arguments->Add(function_args.NodeAt(0));
1444 // The second argument is the invocation mirror. 1464 // The second argument is the invocation mirror.
1445 arguments->Add(BuildInvocationMirrorAllocation( 1465 arguments->Add(BuildInvocationMirrorAllocation(
1446 call_pos, function_name, function_args)); 1466 call_pos, function_name, function_args, temp_for_last_arg));
1447 return arguments; 1467 return arguments;
1448 } 1468 }
1449 1469
1450 1470
1451 AstNode* Parser::ParseSuperCall(const String& function_name) { 1471 AstNode* Parser::ParseSuperCall(const String& function_name) {
1452 TRACE_PARSER("ParseSuperCall"); 1472 TRACE_PARSER("ParseSuperCall");
1453 ASSERT(CurrentToken() == Token::kLPAREN); 1473 ASSERT(CurrentToken() == Token::kLPAREN);
1454 const intptr_t supercall_pos = TokenPos(); 1474 const intptr_t supercall_pos = TokenPos();
1455 1475
1456 // 'this' parameter is the first argument to super call. 1476 // 'this' parameter is the first argument to super call.
(...skipping 5417 matching lines...) Expand 10 before | Expand all | Expand 10 after
6874 ConsumeToken(); 6894 ConsumeToken();
6875 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 6895 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
6876 list->Add(expr); 6896 list->Add(expr);
6877 } 6897 }
6878 expressions = list; 6898 expressions = list;
6879 } 6899 }
6880 return expressions; 6900 return expressions;
6881 } 6901 }
6882 6902
6883 6903
6884 const LocalVariable* Parser::GetIncrementTempLocal() {
6885 if (!parsed_function()->has_expression_temp_var()) {
6886 LocalVariable* temp = ParsedFunction::CreateExpressionTempVar(
6887 current_function().token_pos());
6888 ASSERT(temp != NULL);
6889 parsed_function()->set_expression_temp_var(temp);
6890 }
6891 ASSERT(parsed_function()->has_expression_temp_var());
6892 return parsed_function()->expression_temp_var();
6893 }
6894
6895
6896 void Parser::EnsureExpressionTemp() { 6904 void Parser::EnsureExpressionTemp() {
6897 // Temporary used later by the flow_graph_builder. 6905 // Temporary used later by the flow_graph_builder.
6898 GetIncrementTempLocal(); 6906 parsed_function()->EnsureExpressionTemp();
6899 } 6907 }
6900 6908
6901 6909
6902 void Parser::EnsureSavedCurrentContext() { 6910 void Parser::EnsureSavedCurrentContext() {
6903 // Used later by the flow_graph_builder to save current context. 6911 // Used later by the flow_graph_builder to save current context.
6904 if (!parsed_function()->has_saved_current_context_var()) { 6912 if (!parsed_function()->has_saved_current_context_var()) {
6905 LocalVariable* temp = 6913 LocalVariable* temp =
6906 new LocalVariable(current_function().token_pos(), 6914 new LocalVariable(current_function().token_pos(),
6907 Symbols::SavedCurrentContextVar(), 6915 Symbols::SavedCurrentContextVar(),
6908 Type::ZoneHandle(Type::DynamicType())); 6916 Type::ZoneHandle(Type::DynamicType()));
(...skipping 3051 matching lines...) Expand 10 before | Expand all | Expand 10 after
9960 void Parser::SkipQualIdent() { 9968 void Parser::SkipQualIdent() {
9961 ASSERT(IsIdentifier()); 9969 ASSERT(IsIdentifier());
9962 ConsumeToken(); 9970 ConsumeToken();
9963 if (CurrentToken() == Token::kPERIOD) { 9971 if (CurrentToken() == Token::kPERIOD) {
9964 ConsumeToken(); // Consume the kPERIOD token. 9972 ConsumeToken(); // Consume the kPERIOD token.
9965 ExpectIdentifier("identifier expected after '.'"); 9973 ExpectIdentifier("identifier expected after '.'");
9966 } 9974 }
9967 } 9975 }
9968 9976
9969 } // namespace dart 9977 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/unit_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698