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

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

Issue 10513008: Fix super call invocation (issue 2028). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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') | tests/co19/co19-runtime.status » ('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 "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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 static const char* kListLiteralFactoryName = "List.fromLiteral"; 47 static const char* kListLiteralFactoryName = "List.fromLiteral";
48 static const char* kMapLiteralFactoryClassName = "_MapLiteralFactory"; 48 static const char* kMapLiteralFactoryClassName = "_MapLiteralFactory";
49 static const char* kMapLiteralFactoryName = "Map.fromLiteral"; 49 static const char* kMapLiteralFactoryName = "Map.fromLiteral";
50 static const char* kImmutableMapName = "ImmutableMap"; 50 static const char* kImmutableMapName = "ImmutableMap";
51 static const char* kImmutableMapConstructorName = "ImmutableMap._create"; 51 static const char* kImmutableMapConstructorName = "ImmutableMap._create";
52 static const char* kStringClassName = "StringBase"; 52 static const char* kStringClassName = "StringBase";
53 static const char* kInterpolateName = "_interpolate"; 53 static const char* kInterpolateName = "_interpolate";
54 static const char* kThisName = "this"; 54 static const char* kThisName = "this";
55 static const char* kPhaseParameterName = ":phase"; 55 static const char* kPhaseParameterName = ":phase";
56 static const char* kGetIteratorName = "iterator"; 56 static const char* kGetIteratorName = "iterator";
57 static const char* kNoSuchMethodName = "noSuchMethod";
57 58
58 #if defined(DEBUG) 59 #if defined(DEBUG)
59 60
60 class TraceParser : public ValueObject { 61 class TraceParser : public ValueObject {
61 public: 62 public:
62 TraceParser(intptr_t token_index, const Script& script, const char* msg) { 63 TraceParser(intptr_t token_index, const Script& script, const char* msg) {
63 if (FLAG_trace_parser) { 64 if (FLAG_trace_parser) {
64 intptr_t line, column; 65 intptr_t line, column;
65 script.GetTokenLocation(token_index, &line, &column); 66 script.GetTokenLocation(token_index, &line, &column);
66 PrintIndent(); 67 PrintIndent();
(...skipping 1137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 func = super_cls.LookupDynamicFunction(name); 1205 func = super_cls.LookupDynamicFunction(name);
1205 if (!func.IsNull()) { 1206 if (!func.IsNull()) {
1206 return func.raw(); 1207 return func.raw();
1207 } 1208 }
1208 super_cls = super_cls.SuperClass(); 1209 super_cls = super_cls.SuperClass();
1209 } 1210 }
1210 } 1211 }
1211 return func.raw(); 1212 return func.raw();
1212 } 1213 }
1213 1214
1214 1215 // Resolve and return the dynamic function of the given name in the superclass.
1216 // If it is not found, return noSuchMethod and set is_no_such_method to true.
1215 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, 1217 RawFunction* Parser::GetSuperFunction(intptr_t token_pos,
1216 const String& name) { 1218 const String& name,
1219 bool* is_no_such_method) {
1217 const Class& super_class = Class::Handle(current_class().SuperClass()); 1220 const Class& super_class = Class::Handle(current_class().SuperClass());
1218 if (super_class.IsNull()) { 1221 if (super_class.IsNull()) {
1219 ErrorMsg(token_pos, "class '%s' does not have a superclass", 1222 ErrorMsg(token_pos, "class '%s' does not have a superclass",
1220 String::Handle(current_class().Name()).ToCString()); 1223 String::Handle(current_class().Name()).ToCString());
1221 } 1224 }
1222 1225
1223 const Function& super_func = 1226 Function& super_func =
1224 Function::Handle(ResolveDynamicFunction(super_class, name)); 1227 Function::Handle(ResolveDynamicFunction(super_class, name));
1225 if (super_func.IsNull()) { 1228 if (super_func.IsNull()) {
1226 ErrorMsg(token_pos, "function '%s' not found in super class", 1229 const String& no_such_method_name =
1227 name.ToCString()); 1230 String::ZoneHandle(String::NewSymbol(kNoSuchMethodName));
1231 super_func = ResolveDynamicFunction(super_class, no_such_method_name);
srdjan 2012/06/04 23:31:07 Is it specified whose noSuchMethod should be invok
regis 2012/06/13 22:15:50 It must be resolved in the super class, which we d
1232 ASSERT(!super_func.IsNull());
1233 *is_no_such_method = true;
1234 } else {
1235 *is_no_such_method = false;
1228 } 1236 }
1229 CheckFunctionIsCallable(token_pos, super_func); 1237 CheckFunctionIsCallable(token_pos, super_func);
1230 return super_func.raw(); 1238 return super_func.raw();
1231 } 1239 }
1232 1240
1233 1241
1242 // Lookup class in the corelib implementation which contains various VM
1243 // helper methods and classes.
1244 static RawClass* LookupImplClass(const String& class_name) {
1245 return Library::Handle(Library::CoreImplLibrary()).LookupClass(class_name);
1246 }
1247
1248
1249 // Lookup class in the corelib which also contains various VM
1250 // helper methods and classes. Allow look up of private classes.
1251 static RawClass* LookupCoreClass(const String& class_name) {
1252 const Library& core_lib = Library::Handle(Library::CoreLibrary());
1253 String& name = String::Handle(class_name.raw());
1254 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) {
1255 // Private identifiers are mangled on a per script basis.
1256 name = String::Concat(name, String::Handle(core_lib.private_key()));
1257 name = String::NewSymbol(name);
1258 }
1259 return core_lib.LookupClass(name);
1260 }
1261
1262
1263 ArgumentListNode* Parser::BuildNoSuchMethodArguments(
1264 const String& function_name,
1265 ArgumentListNode* function_args) {
srdjan 2012/06/04 23:31:07 const ArgumentListNode&
regis 2012/06/13 22:15:50 Done.
1266 ASSERT(function_args->length() >= 1); // The receiver is the first argument.
1267 const intptr_t args_pos = function_args->token_index();
1268 ArgumentListNode* arguments = new ArgumentListNode(args_pos);
1269 arguments->Add(function_args->NodeAt(0));
1270 // The second argument is the original function name.
1271 // TODO(regis): This will change once mirrors are supported.
1272 arguments->Add(new LiteralNode(args_pos, function_name));
1273 // The third argument is an array containing the original function arguments.
1274 ArrayNode* args_array = new ArrayNode(args_pos, TypeArguments::ZoneHandle());
1275 for (intptr_t i = 1; i < function_args->length(); i++) {
1276 args_array->AddElement(function_args->NodeAt(i));
1277 }
1278 // Call the list factory to create an array from the original arguments.
1279 String& list_literal_factory_class_name = String::Handle(
1280 String::NewSymbol(kListLiteralFactoryClassName));
1281 const Class& list_literal_factory_class =
1282 Class::Handle(LookupCoreClass(list_literal_factory_class_name));
1283 ASSERT(!list_literal_factory_class.IsNull());
1284 const String& list_literal_factory_name =
1285 String::Handle(String::NewSymbol(kListLiteralFactoryName));
1286 const Function& list_literal_factory = Function::ZoneHandle(
1287 list_literal_factory_class.LookupFactory(list_literal_factory_name));
1288 ASSERT(!list_literal_factory.IsNull());
1289 ArgumentListNode* factory_param = new ArgumentListNode(args_pos);
1290 factory_param->Add(args_array);
1291 AstNode* original_args =
1292 CreateConstructorCallNode(args_pos,
1293 TypeArguments::ZoneHandle(),
1294 list_literal_factory,
1295 factory_param);
1296 arguments->Add(original_args);
1297 return arguments;
1298 }
1299
1300
1234 AstNode* Parser::ParseSuperCall(const String& function_name) { 1301 AstNode* Parser::ParseSuperCall(const String& function_name) {
1235 TRACE_PARSER("ParseSuperCall"); 1302 TRACE_PARSER("ParseSuperCall");
1236 ASSERT(CurrentToken() == Token::kLPAREN); 1303 ASSERT(CurrentToken() == Token::kLPAREN);
1237 const intptr_t supercall_pos = token_index_; 1304 const intptr_t supercall_pos = token_index_;
1238 1305
1306 bool is_no_such_method = false;
1239 const Function& super_function = Function::ZoneHandle( 1307 const Function& super_function = Function::ZoneHandle(
1240 GetSuperFunction(supercall_pos, function_name)); 1308 GetSuperFunction(supercall_pos, function_name, &is_no_such_method));
1241 1309
1242 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); 1310 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1243 // 'this' parameter is the first argument to super call. 1311 // 'this' parameter is the first argument to super call.
1244 AstNode* receiver = LoadReceiver(supercall_pos); 1312 AstNode* receiver = LoadReceiver(supercall_pos);
1245 arguments->Add(receiver); 1313 arguments->Add(receiver);
1246 ParseActualParameters(arguments, kAllowConst); 1314 ParseActualParameters(arguments, kAllowConst);
1315 if (is_no_such_method) {
1316 arguments = BuildNoSuchMethodArguments(function_name, arguments);
1317 }
1247 return new StaticCallNode(supercall_pos, super_function, arguments); 1318 return new StaticCallNode(supercall_pos, super_function, arguments);
1248 } 1319 }
1249 1320
1250 1321
1251 // Simple test if a node is side effect free. 1322 // Simple test if a node is side effect free.
1252 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { 1323 static bool IsSimpleLocalOrLiteralNode(AstNode* node) {
1253 if (node->IsLiteralNode()) { 1324 if (node->IsLiteralNode()) {
1254 return true; 1325 return true;
1255 } 1326 }
1256 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { 1327 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) {
(...skipping 24 matching lines...) Expand all
1281 AstNode* save = 1352 AstNode* save =
1282 new StoreLocalNode(operator_pos, *temp, index_expr); 1353 new StoreLocalNode(operator_pos, *temp, index_expr);
1283 current_block_->statements->Add(save); 1354 current_block_->statements->Add(save);
1284 index_expr = new LoadLocalNode(operator_pos, *temp); 1355 index_expr = new LoadLocalNode(operator_pos, *temp);
1285 } 1356 }
1286 } 1357 }
1287 1358
1288 // Resolve the [] operator function in the superclass. 1359 // Resolve the [] operator function in the superclass.
1289 const String& index_operator_name = 1360 const String& index_operator_name =
1290 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); 1361 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX)));
1362 bool is_no_such_method = false;
1291 const Function& index_operator = Function::ZoneHandle( 1363 const Function& index_operator = Function::ZoneHandle(
1292 GetSuperFunction(operator_pos, index_operator_name)); 1364 GetSuperFunction(operator_pos,
1365 index_operator_name,
1366 &is_no_such_method));
1293 1367
1294 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos); 1368 ArgumentListNode* index_op_arguments = new ArgumentListNode(operator_pos);
1295 AstNode* receiver = LoadReceiver(operator_pos); 1369 AstNode* receiver = LoadReceiver(operator_pos);
1296 index_op_arguments->Add(receiver); 1370 index_op_arguments->Add(receiver);
1297 index_op_arguments->Add(index_expr); 1371 index_op_arguments->Add(index_expr);
1298 1372
1373 if (is_no_such_method) {
1374 index_op_arguments = BuildNoSuchMethodArguments(index_operator_name,
1375 index_op_arguments);
1376 }
1299 super_op = new StaticCallNode( 1377 super_op = new StaticCallNode(
1300 operator_pos, index_operator, index_op_arguments); 1378 operator_pos, index_operator, index_op_arguments);
1301 1379
1302 if (Token::IsAssignmentOperator(CurrentToken())) { 1380 if (Token::IsAssignmentOperator(CurrentToken())) {
1303 Token::Kind assignment_op = CurrentToken(); 1381 Token::Kind assignment_op = CurrentToken();
1304 ConsumeToken(); 1382 ConsumeToken();
1305 AstNode* value = ParseExpr(kAllowConst); 1383 AstNode* value = ParseExpr(kAllowConst);
1306 1384
1307 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value); 1385 value = ExpandAssignableOp(operator_pos, assignment_op, super_op, value);
1308 1386
1309 // Resolve the []= operator function in the superclass. 1387 // Resolve the []= operator function in the superclass.
1310 const String& assign_index_operator_name = String::ZoneHandle( 1388 const String& assign_index_operator_name = String::ZoneHandle(
1311 String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); 1389 String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
1390 bool is_no_such_method = false;
1312 const Function& assign_index_operator = Function::ZoneHandle( 1391 const Function& assign_index_operator = Function::ZoneHandle(
1313 GetSuperFunction(operator_pos, assign_index_operator_name)); 1392 GetSuperFunction(operator_pos,
1393 assign_index_operator_name,
1394 &is_no_such_method));
1314 1395
1315 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos); 1396 ArgumentListNode* operator_args = new ArgumentListNode(operator_pos);
1316 operator_args->Add(LoadReceiver(operator_pos)); 1397 operator_args->Add(LoadReceiver(operator_pos));
1317 operator_args->Add(index_expr); 1398 operator_args->Add(index_expr);
1318 operator_args->Add(value); 1399 operator_args->Add(value);
1319 1400
1401 if (is_no_such_method) {
1402 operator_args = BuildNoSuchMethodArguments(assign_index_operator_name,
1403 operator_args);
1404 }
1320 super_op = new StaticCallNode( 1405 super_op = new StaticCallNode(
1321 operator_pos, assign_index_operator, operator_args); 1406 operator_pos, assign_index_operator, operator_args);
1322 } 1407 }
1323 } else if (Token::CanBeOverloaded(CurrentToken())) { 1408 } else if (Token::CanBeOverloaded(CurrentToken())) {
1324 Token::Kind op = CurrentToken(); 1409 Token::Kind op = CurrentToken();
1325 ConsumeToken(); 1410 ConsumeToken();
1326 1411
1327 // Resolve the operator function in the superclass. 1412 // Resolve the operator function in the superclass.
1328 const String& operator_function_name = 1413 const String& operator_function_name =
1329 String::Handle(String::NewSymbol(Token::Str(op))); 1414 String::Handle(String::NewSymbol(Token::Str(op)));
1415 bool is_no_such_method = false;
1330 const Function& super_operator = Function::ZoneHandle( 1416 const Function& super_operator = Function::ZoneHandle(
1331 GetSuperFunction(operator_pos, operator_function_name)); 1417 GetSuperFunction(operator_pos,
1418 operator_function_name,
1419 &is_no_such_method));
1332 1420
1333 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR)); 1421 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR));
1334 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); 1422 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1);
1335 1423
1336 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); 1424 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos);
1337 AstNode* receiver = LoadReceiver(operator_pos); 1425 AstNode* receiver = LoadReceiver(operator_pos);
1338 op_arguments->Add(receiver); 1426 op_arguments->Add(receiver);
1339 op_arguments->Add(other_operand); 1427 op_arguments->Add(other_operand);
1340 1428
1341 CheckFunctionIsCallable(operator_pos, super_operator); 1429 CheckFunctionIsCallable(operator_pos, super_operator);
1430 if (is_no_such_method) {
1431 op_arguments = BuildNoSuchMethodArguments(operator_function_name,
1432 op_arguments);
1433 }
1342 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); 1434 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments);
1343 } 1435 }
1344 return super_op; 1436 return super_op;
1345 } 1437 }
1346 1438
1347 1439
1348 AstNode* Parser::CreateImplicitClosureNode(const Function& func, 1440 AstNode* Parser::CreateImplicitClosureNode(const Function& func,
1349 intptr_t token_pos, 1441 intptr_t token_pos,
1350 AstNode* receiver) { 1442 AstNode* receiver) {
1351 Function& implicit_closure_function = 1443 Function& implicit_closure_function =
(...skipping 3575 matching lines...) Expand 10 before | Expand all | Expand 10 after
4927 CloseBlock(); 5019 CloseBlock();
4928 return new ForNode(for_pos, 5020 return new ForNode(for_pos,
4929 label, 5021 label,
4930 NodeAsSequenceNode(init_pos, initializer, init_scope), 5022 NodeAsSequenceNode(init_pos, initializer, init_scope),
4931 condition, 5023 condition,
4932 NodeAsSequenceNode(incr_pos, increment, incr_scope), 5024 NodeAsSequenceNode(incr_pos, increment, incr_scope),
4933 body); 5025 body);
4934 } 5026 }
4935 5027
4936 5028
4937 // Lookup class in the corelib implementation which contains various VM
4938 // helper methods and classes.
4939 static RawClass* LookupImplClass(const String& class_name) {
4940 return Library::Handle(Library::CoreImplLibrary()).LookupClass(class_name);
4941 }
4942
4943
4944 // Lookup class in the corelib which also contains various VM
4945 // helper methods and classes. Allow look up of private classes.
4946 static RawClass* LookupCoreClass(const String& class_name) {
4947 const Library& core_lib = Library::Handle(Library::CoreLibrary());
4948 String& name = String::Handle(class_name.raw());
4949 if (class_name.CharAt(0) == Scanner::kPrivateIdentifierStart) {
4950 // Private identifiers are mangled on a per script basis.
4951 name = String::Concat(name, String::Handle(core_lib.private_key()));
4952 name = String::NewSymbol(name);
4953 }
4954 return core_lib.LookupClass(name);
4955 }
4956
4957
4958 // Calling VM-internal helpers, uses implementation core library. 5029 // Calling VM-internal helpers, uses implementation core library.
4959 AstNode* Parser::MakeStaticCall(const char* class_name, 5030 AstNode* Parser::MakeStaticCall(const char* class_name,
4960 const char* function_name, 5031 const char* function_name,
4961 ArgumentListNode* arguments) { 5032 ArgumentListNode* arguments) {
4962 const String& cls_name = 5033 const String& cls_name =
4963 String::Handle(String::NewSymbol(class_name)); 5034 String::Handle(String::NewSymbol(class_name));
4964 const Class& cls = Class::Handle(LookupImplClass(cls_name)); 5035 const Class& cls = Class::Handle(LookupImplClass(cls_name));
4965 ASSERT(!cls.IsNull()); 5036 ASSERT(!cls.IsNull());
4966 const String& func_name = 5037 const String& func_name =
4967 String::ZoneHandle(String::NewSymbol(function_name)); 5038 String::ZoneHandle(String::NewSymbol(function_name));
(...skipping 3565 matching lines...) Expand 10 before | Expand all | Expand 10 after
8533 void Parser::SkipQualIdent() { 8604 void Parser::SkipQualIdent() {
8534 ASSERT(IsIdentifier()); 8605 ASSERT(IsIdentifier());
8535 ConsumeToken(); 8606 ConsumeToken();
8536 if (CurrentToken() == Token::kPERIOD) { 8607 if (CurrentToken() == Token::kPERIOD) {
8537 ConsumeToken(); // Consume the kPERIOD token. 8608 ConsumeToken(); // Consume the kPERIOD token.
8538 ExpectIdentifier("identifier expected after '.'"); 8609 ExpectIdentifier("identifier expected after '.'");
8539 } 8610 }
8540 } 8611 }
8541 8612
8542 } // namespace dart 8613 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698