Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 504 AbstractType& type_argument = AbstractType::Handle(); | 504 AbstractType& type_argument = AbstractType::Handle(); |
| 505 for (intptr_t i = 0; i < num_arguments; i++) { | 505 for (intptr_t i = 0; i < num_arguments; i++) { |
| 506 type_argument = arguments.TypeAt(i); | 506 type_argument = arguments.TypeAt(i); |
| 507 ResolveType(cls, type_argument, finalization); | 507 ResolveType(cls, type_argument, finalization); |
| 508 } | 508 } |
| 509 } | 509 } |
| 510 } | 510 } |
| 511 | 511 |
| 512 | 512 |
| 513 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { | 513 void ClassFinalizer::FinalizeTypeParameters(const Class& cls) { |
| 514 if (cls.mixin() != Type::null()) { | |
|
siva
2013/09/04 21:07:00
Might be more readable to have a isMixin() method
regis
2013/09/04 22:14:27
Added IsMixinApplication() to class Class.
| |
| 515 // Copy the type parameters to the mixin application. | |
| 516 ApplyMixinType(cls); | |
| 517 } | |
| 514 // The type parameter bounds are not finalized here. | 518 // The type parameter bounds are not finalized here. |
| 515 const TypeArguments& type_parameters = | 519 const TypeArguments& type_parameters = |
| 516 TypeArguments::Handle(cls.type_parameters()); | 520 TypeArguments::Handle(cls.type_parameters()); |
| 517 if (!type_parameters.IsNull()) { | 521 if (!type_parameters.IsNull()) { |
| 518 TypeParameter& type_parameter = TypeParameter::Handle(); | 522 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 519 const intptr_t num_types = type_parameters.Length(); | 523 const intptr_t num_types = type_parameters.Length(); |
| 520 for (intptr_t i = 0; i < num_types; i++) { | 524 for (intptr_t i = 0; i < num_types; i++) { |
| 521 type_parameter ^= type_parameters.TypeAt(i); | 525 type_parameter ^= type_parameters.TypeAt(i); |
| 522 type_parameter ^= FinalizeType(cls, | 526 type_parameter ^= FinalizeType(cls, |
| 523 type_parameter, | 527 type_parameter, |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1303 } | 1307 } |
| 1304 } | 1308 } |
| 1305 } | 1309 } |
| 1306 } | 1310 } |
| 1307 | 1311 |
| 1308 | 1312 |
| 1309 // Copy the type parameters of the super and mixin classes to the | 1313 // Copy the type parameters of the super and mixin classes to the |
| 1310 // mixin application class. Change type arguments of super type and of | 1314 // mixin application class. Change type arguments of super type and of |
| 1311 // interfaces to refer to the respective type parameters of the mixin | 1315 // interfaces to refer to the respective type parameters of the mixin |
| 1312 // application class. | 1316 // application class. |
| 1313 void ClassFinalizer::CloneTypeParameters(const Class& mixapp_class) { | 1317 void ClassFinalizer::CloneTypeParameters(const Class& mixin_app_class) { |
| 1314 ASSERT(mixapp_class.NumTypeParameters() == 0); | 1318 ASSERT(mixin_app_class.type_parameters() == AbstractTypeArguments::null()); |
| 1315 | 1319 |
| 1316 const AbstractType& super_type = | 1320 const AbstractType& super_type = |
| 1317 AbstractType::Handle(mixapp_class.super_type()); | 1321 AbstractType::Handle(mixin_app_class.super_type()); |
| 1318 ASSERT(super_type.IsResolved()); | 1322 ASSERT(super_type.IsResolved()); |
| 1319 const Class& super_class = Class::Handle(super_type.type_class()); | 1323 const Class& super_class = Class::Handle(super_type.type_class()); |
| 1320 const Type& mixin_type = Type::Handle(mixapp_class.mixin()); | 1324 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); |
| 1321 const Class& mixin_class = Class::Handle(mixin_type.type_class()); | 1325 const Class& mixin_class = Class::Handle(mixin_type.type_class()); |
| 1322 const int num_super_parameters = super_class.NumTypeParameters(); | 1326 const int num_super_parameters = super_class.NumTypeParameters(); |
| 1323 const int num_mixin_parameters = mixin_class.NumTypeParameters(); | 1327 const int num_mixin_parameters = mixin_class.NumTypeParameters(); |
| 1324 if ((num_super_parameters + num_mixin_parameters) == 0) { | 1328 if ((num_super_parameters + num_mixin_parameters) == 0) { |
| 1325 return; | 1329 return; |
| 1326 } | 1330 } |
| 1327 | 1331 |
| 1328 // First, clone the super class type parameters. Rename them so that | 1332 // First, clone the super class type parameters. Rename them so that |
| 1329 // there can be no name conflict between the parameters of the super | 1333 // there can be no name conflict between the parameters of the super |
| 1330 // class and the mixin class. | 1334 // class and the mixin class. |
| 1331 const TypeArguments& cloned_type_params = TypeArguments::Handle( | 1335 const TypeArguments& cloned_type_params = TypeArguments::Handle( |
| 1332 TypeArguments::New(num_super_parameters + num_mixin_parameters)); | 1336 TypeArguments::New(num_super_parameters + num_mixin_parameters)); |
| 1333 TypeParameter& param = TypeParameter::Handle(); | 1337 TypeParameter& param = TypeParameter::Handle(); |
| 1334 TypeParameter& cloned_param = TypeParameter::Handle(); | 1338 TypeParameter& cloned_param = TypeParameter::Handle(); |
| 1335 String& param_name = String::Handle(); | 1339 String& param_name = String::Handle(); |
| 1336 AbstractType& param_bound = AbstractType::Handle(); | 1340 AbstractType& param_bound = AbstractType::Handle(); |
| 1337 int cloned_index = 0; | 1341 int cloned_index = 0; |
| 1338 if (num_super_parameters > 0) { | 1342 if (num_super_parameters > 0) { |
| 1339 const TypeArguments& super_params = | 1343 const TypeArguments& super_params = |
| 1340 TypeArguments::Handle(super_class.type_parameters()); | 1344 TypeArguments::Handle(super_class.type_parameters()); |
| 1341 const TypeArguments& super_type_args = | 1345 const TypeArguments& super_type_args = |
| 1342 TypeArguments::Handle(TypeArguments::New(num_super_parameters)); | 1346 TypeArguments::Handle(TypeArguments::New(num_super_parameters)); |
| 1343 for (int i = 0; i < num_super_parameters; i++) { | 1347 for (int i = 0; i < num_super_parameters; i++) { |
| 1344 param ^= super_params.TypeAt(i); | 1348 param ^= super_params.TypeAt(i); |
| 1345 param_name = param.name(); | 1349 param_name = param.name(); |
| 1346 param_bound = param.bound(); | 1350 param_bound = param.bound(); |
| 1347 // TODO(hausner): handle type bounds. | 1351 // TODO(hausner): handle type bounds. |
| 1348 if (!param_bound.IsObjectType()) { | 1352 if (!param_bound.IsObjectType()) { |
| 1349 const Script& script = Script::Handle(mixapp_class.script()); | 1353 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1350 ReportError(Error::Handle(), // No previous error. | 1354 ReportError(Error::Handle(), // No previous error. |
| 1351 script, param.token_pos(), | 1355 script, param.token_pos(), |
| 1352 "type parameter '%s': type bounds not yet" | 1356 "type parameter '%s': type bounds not yet" |
| 1353 " implemented for mixins\n", | 1357 " implemented for mixins\n", |
| 1354 param_name.ToCString()); | 1358 param_name.ToCString()); |
| 1355 } | 1359 } |
| 1356 param_name = String::Concat(param_name, Symbols::Backtick()); | 1360 param_name = String::Concat(param_name, Symbols::Backtick()); |
| 1357 param_name = Symbols::New(param_name); | 1361 param_name = Symbols::New(param_name); |
| 1358 cloned_param = TypeParameter::New(mixapp_class, | 1362 cloned_param = TypeParameter::New(mixin_app_class, |
| 1359 cloned_index, | 1363 cloned_index, |
| 1360 param_name, | 1364 param_name, |
| 1361 param_bound, | 1365 param_bound, |
| 1362 param.token_pos()); | 1366 param.token_pos()); |
| 1363 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1367 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1364 // Change the type arguments of the super type to refer to the | 1368 // Change the type arguments of the super type to refer to the |
| 1365 // cloned type parameters of the mixin application class. | 1369 // cloned type parameters of the mixin application class. |
| 1366 super_type_args.SetTypeAt(cloned_index, cloned_param); | 1370 super_type_args.SetTypeAt(cloned_index, cloned_param); |
| 1367 cloned_index++; | 1371 cloned_index++; |
| 1368 } | 1372 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1382 TypeArguments::Handle(mixin_class.type_parameters()); | 1386 TypeArguments::Handle(mixin_class.type_parameters()); |
| 1383 const TypeArguments& interface_type_args = TypeArguments::Handle( | 1387 const TypeArguments& interface_type_args = TypeArguments::Handle( |
| 1384 TypeArguments::New(num_mixin_parameters)); | 1388 TypeArguments::New(num_mixin_parameters)); |
| 1385 for (int i = 0; i < num_mixin_parameters; i++) { | 1389 for (int i = 0; i < num_mixin_parameters; i++) { |
| 1386 param ^= mixin_params.TypeAt(i); | 1390 param ^= mixin_params.TypeAt(i); |
| 1387 param_name = param.name(); | 1391 param_name = param.name(); |
| 1388 param_bound = param.bound(); | 1392 param_bound = param.bound(); |
| 1389 | 1393 |
| 1390 // TODO(hausner): handle type bounds. | 1394 // TODO(hausner): handle type bounds. |
| 1391 if (!param_bound.IsObjectType()) { | 1395 if (!param_bound.IsObjectType()) { |
| 1392 const Script& script = Script::Handle(mixapp_class.script()); | 1396 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1393 ReportError(Error::Handle(), // No previous error. | 1397 ReportError(Error::Handle(), // No previous error. |
| 1394 script, param.token_pos(), | 1398 script, param.token_pos(), |
| 1395 "type parameter '%s': type bounds not yet" | 1399 "type parameter '%s': type bounds not yet" |
| 1396 " implemented for mixins\n", | 1400 " implemented for mixins\n", |
| 1397 param_name.ToCString()); | 1401 param_name.ToCString()); |
| 1398 } | 1402 } |
| 1399 cloned_param = TypeParameter::New(mixapp_class, | 1403 cloned_param = TypeParameter::New(mixin_app_class, |
| 1400 cloned_index, | 1404 cloned_index, |
| 1401 param_name, | 1405 param_name, |
| 1402 param_bound, | 1406 param_bound, |
| 1403 param.token_pos()); | 1407 param.token_pos()); |
| 1404 cloned_type_params.SetTypeAt(cloned_index, cloned_param); | 1408 cloned_type_params.SetTypeAt(cloned_index, cloned_param); |
| 1405 interface_type_args.SetTypeAt(i, cloned_param); | 1409 interface_type_args.SetTypeAt(i, cloned_param); |
| 1406 cloned_index++; | 1410 cloned_index++; |
| 1407 } | 1411 } |
| 1408 | 1412 |
| 1409 // Lastly, change the type arguments of the single interface type to | 1413 // Lastly, change the type arguments of the single interface type to |
| 1410 // refer to the cloned type parameters of the mixin application class. | 1414 // refer to the cloned type parameters of the mixin application class. |
| 1411 Array& interface_types = Array::Handle(mixapp_class.interfaces()); | 1415 Array& interface_types = Array::Handle(mixin_app_class.interfaces()); |
| 1412 ASSERT(interface_types.Length() == 1); | 1416 ASSERT(interface_types.Length() == 1); |
| 1413 AbstractType& interface_type = AbstractType::Handle(); | 1417 AbstractType& interface_type = AbstractType::Handle(); |
| 1414 interface_type ^= interface_types.At(0); | 1418 interface_type ^= interface_types.At(0); |
| 1415 ASSERT(interface_type.IsResolved()); | 1419 ASSERT(interface_type.IsResolved()); |
| 1416 // TODO(hausner): May need to handle BoundedType here. | 1420 // TODO(hausner): May need to handle BoundedType here. |
| 1417 ASSERT(interface_type.IsType()); | 1421 ASSERT(interface_type.IsType()); |
| 1418 Type::Cast(interface_type).set_arguments(interface_type_args); | 1422 Type::Cast(interface_type).set_arguments(interface_type_args); |
| 1419 ASSERT(!interface_type.IsFinalized()); | 1423 ASSERT(!interface_type.IsFinalized()); |
| 1420 } | 1424 } |
| 1421 mixapp_class.set_type_parameters(cloned_type_params); | 1425 mixin_app_class.set_type_parameters(cloned_type_params); |
| 1422 } | 1426 } |
| 1423 | 1427 |
| 1424 | 1428 |
| 1425 void ClassFinalizer::ApplyMixinTypes(const Class& cls) { | 1429 void ClassFinalizer::ApplyMixinType(const Class& mixin_app_class) { |
| 1426 const Type& mixin_type = Type::Handle(cls.mixin()); | 1430 if (mixin_app_class.is_mixin_type_applied()) { |
| 1431 return; | |
| 1432 } | |
| 1433 const Type& mixin_type = Type::Handle(mixin_app_class.mixin()); | |
| 1427 ASSERT(!mixin_type.IsNull()); | 1434 ASSERT(!mixin_type.IsNull()); |
| 1428 ASSERT(mixin_type.HasResolvedTypeClass()); | 1435 ASSERT(mixin_type.HasResolvedTypeClass()); |
| 1429 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); | 1436 const Class& mixin_cls = Class::Handle(mixin_type.type_class()); |
| 1430 | 1437 |
| 1431 if (FLAG_trace_class_finalization) { | 1438 if (FLAG_trace_class_finalization) { |
| 1432 OS::Print("Applying mixin type '%s' to '%s' at pos %" Pd "\n", | 1439 OS::Print("Applying mixin type '%s' to '%s' at pos %" Pd "\n", |
| 1433 String::Handle(mixin_type.Name()).ToCString(), | 1440 String::Handle(mixin_type.Name()).ToCString(), |
| 1434 cls.ToCString(), | 1441 mixin_app_class.ToCString(), |
| 1435 cls.token_pos()); | 1442 mixin_app_class.token_pos()); |
| 1436 } | 1443 } |
| 1437 | 1444 |
| 1438 // Check that the super class of the mixin class is extending | 1445 // Check that the super class of the mixin class is extending |
| 1439 // class Object. | 1446 // class Object. |
| 1440 const AbstractType& mixin_super_type = | 1447 const AbstractType& mixin_super_type = |
| 1441 AbstractType::Handle(mixin_cls.super_type()); | 1448 AbstractType::Handle(mixin_cls.super_type()); |
| 1442 if (!mixin_super_type.IsObjectType()) { | 1449 if (!mixin_super_type.IsObjectType()) { |
| 1443 const Script& script = Script::Handle(cls.script()); | 1450 const Script& script = Script::Handle(mixin_app_class.script()); |
| 1444 const String& class_name = String::Handle(mixin_cls.Name()); | 1451 const String& class_name = String::Handle(mixin_cls.Name()); |
| 1445 ReportError(Error::Handle(), // No previous error. | 1452 ReportError(Error::Handle(), // No previous error. |
| 1446 script, cls.token_pos(), | 1453 script, mixin_app_class.token_pos(), |
| 1447 "mixin class %s must extend class Object", | 1454 "mixin class %s must extend class Object", |
| 1448 class_name.ToCString()); | 1455 class_name.ToCString()); |
| 1449 } | 1456 } |
| 1450 | 1457 |
| 1451 // Copy type parameters to mixin application class. | 1458 // Copy type parameters to mixin application class. |
| 1452 CloneTypeParameters(cls); | 1459 CloneTypeParameters(mixin_app_class); |
| 1453 | 1460 |
| 1454 if (FLAG_trace_class_finalization) { | 1461 if (FLAG_trace_class_finalization) { |
| 1455 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n", | 1462 OS::Print("Done applying mixin type '%s' to class %s %s extending '%s'\n", |
| 1456 String::Handle(mixin_type.Name()).ToCString(), | 1463 String::Handle(mixin_type.Name()).ToCString(), |
| 1457 String::Handle(cls.Name()).ToCString(), | 1464 String::Handle(mixin_app_class.Name()).ToCString(), |
| 1458 TypeArguments::Handle(cls.type_parameters()).ToCString(), | 1465 TypeArguments::Handle( |
| 1459 AbstractType::Handle(cls.super_type()).ToCString()); | 1466 mixin_app_class.type_parameters()).ToCString(), |
| 1467 AbstractType::Handle(mixin_app_class.super_type()).ToCString()); | |
| 1460 } | 1468 } |
| 1469 mixin_app_class.set_is_mixin_type_applied(); | |
| 1461 } | 1470 } |
| 1462 | 1471 |
| 1463 | 1472 |
| 1464 void ClassFinalizer::CreateForwardingConstructors( | 1473 void ClassFinalizer::CreateForwardingConstructors( |
| 1465 const Class& mixin_app, | 1474 const Class& mixin_app, |
| 1466 const GrowableObjectArray& cloned_funcs) { | 1475 const GrowableObjectArray& cloned_funcs) { |
| 1467 const String& mixin_name = String::Handle(mixin_app.Name()); | 1476 const String& mixin_name = String::Handle(mixin_app.Name()); |
| 1468 const Class& super_class = Class::Handle(mixin_app.SuperClass()); | 1477 const Class& super_class = Class::Handle(mixin_app.SuperClass()); |
| 1469 const String& super_name = String::Handle(super_class.Name()); | 1478 const String& super_name = String::Handle(super_class.Name()); |
| 1470 const Type& dynamic_type = Type::Handle(Type::DynamicType()); | 1479 const Type& dynamic_type = Type::Handle(Type::DynamicType()); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1603 ReportError(Error::Handle(), // No previous error. | 1612 ReportError(Error::Handle(), // No previous error. |
| 1604 script, cls.token_pos(), | 1613 script, cls.token_pos(), |
| 1605 "class '%s' has a cycle in its superclass relationship", | 1614 "class '%s' has a cycle in its superclass relationship", |
| 1606 name.ToCString()); | 1615 name.ToCString()); |
| 1607 } | 1616 } |
| 1608 // Finalize super class. | 1617 // Finalize super class. |
| 1609 const Class& super_class = Class::Handle(cls.SuperClass()); | 1618 const Class& super_class = Class::Handle(cls.SuperClass()); |
| 1610 if (!super_class.IsNull()) { | 1619 if (!super_class.IsNull()) { |
| 1611 FinalizeTypesInClass(super_class); | 1620 FinalizeTypesInClass(super_class); |
| 1612 } | 1621 } |
| 1613 if (cls.mixin() != Type::null()) { | |
| 1614 // Copy the type parameters to the mixin application. | |
| 1615 ApplyMixinTypes(cls); | |
| 1616 } | |
| 1617 // Finalize type parameters before finalizing the super type. | 1622 // Finalize type parameters before finalizing the super type. |
| 1618 FinalizeTypeParameters(cls); | 1623 FinalizeTypeParameters(cls); |
| 1619 ResolveUpperBounds(cls); | 1624 ResolveUpperBounds(cls); |
| 1620 // Finalize super type. | 1625 // Finalize super type. |
| 1621 AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 1626 AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 1622 if (!super_type.IsNull()) { | 1627 if (!super_type.IsNull()) { |
| 1623 // In case of a bound error in the super type in production mode, the | 1628 // In case of a bound error in the super type in production mode, the |
| 1624 // finalized super type will be a BoundedType with a malformed bound. | 1629 // finalized super type will be a BoundedType with a malformed bound. |
| 1625 // It should not be a problem if the class is written to a snapshot and | 1630 // It should not be a problem if the class is written to a snapshot and |
| 1626 // later executed in checked mode. Note that the finalized type argument | 1631 // later executed in checked mode. Note that the finalized type argument |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1853 AbstractTypeArguments& type_args = | 1858 AbstractTypeArguments& type_args = |
| 1854 AbstractTypeArguments::Handle(type.arguments()); | 1859 AbstractTypeArguments::Handle(type.arguments()); |
| 1855 const intptr_t num_type_parameters = type_class.NumTypeParameters(); | 1860 const intptr_t num_type_parameters = type_class.NumTypeParameters(); |
| 1856 const intptr_t num_type_arguments = | 1861 const intptr_t num_type_arguments = |
| 1857 type_args.IsNull() ? 0 : type_args.Length(); | 1862 type_args.IsNull() ? 0 : type_args.Length(); |
| 1858 AbstractType& arg = AbstractType::Handle(); | 1863 AbstractType& arg = AbstractType::Handle(); |
| 1859 if (num_type_arguments > 0) { | 1864 if (num_type_arguments > 0) { |
| 1860 if (num_type_arguments != num_type_parameters) { | 1865 if (num_type_arguments != num_type_parameters) { |
| 1861 const Script& script = Script::Handle(cls.script()); | 1866 const Script& script = Script::Handle(cls.script()); |
| 1862 const String& type_class_name = String::Handle(type_class.Name()); | 1867 const String& type_class_name = String::Handle(type_class.Name()); |
| 1868 // TODO(regis): This should not be a compile time error anymore. | |
| 1863 ReportError(Error::Handle(), // No previous error. | 1869 ReportError(Error::Handle(), // No previous error. |
| 1864 script, type.token_pos(), | 1870 script, type.token_pos(), |
| 1865 "wrong number of type arguments for class '%s'", | 1871 "wrong number of type arguments for class '%s'", |
| 1866 type_class_name.ToCString()); | 1872 type_class_name.ToCString()); |
| 1867 } | 1873 } |
| 1868 for (int i = 0; i < num_type_arguments; i++) { | 1874 for (int i = 0; i < num_type_arguments; i++) { |
| 1869 arg = type_args.TypeAt(i); | 1875 arg = type_args.TypeAt(i); |
| 1870 collected_args.Add(arg); | 1876 collected_args.Add(arg); |
| 1871 } | 1877 } |
| 1872 } else { | 1878 } else { |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2322 expected_name ^= String::New("_offset"); | 2328 expected_name ^= String::New("_offset"); |
| 2323 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); | 2329 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); |
| 2324 field ^= fields_array.At(2); | 2330 field ^= fields_array.At(2); |
| 2325 ASSERT(field.Offset() == TypedDataView::length_offset()); | 2331 ASSERT(field.Offset() == TypedDataView::length_offset()); |
| 2326 name ^= field.name(); | 2332 name ^= field.name(); |
| 2327 ASSERT(name.Equals("length")); | 2333 ASSERT(name.Equals("length")); |
| 2328 #endif | 2334 #endif |
| 2329 } | 2335 } |
| 2330 | 2336 |
| 2331 } // namespace dart | 2337 } // namespace dart |
| OLD | NEW |