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

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

Issue 75713002: Distinguish between malformed and malbounded types more efficiently using the (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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/class_finalizer.h ('k') | runtime/vm/code_generator.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) 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/code_generator.h" 7 #include "vm/code_generator.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 const Function& target = Function::Handle(factory.RedirectionTarget()); 279 const Function& target = Function::Handle(factory.RedirectionTarget());
280 if (target.IsNull()) { 280 if (target.IsNull()) {
281 Type& type = Type::Handle(factory.RedirectionType()); 281 Type& type = Type::Handle(factory.RedirectionType());
282 if (!type.IsMalformed()) { 282 if (!type.IsMalformed()) {
283 const GrowableObjectArray& visited_factories = 283 const GrowableObjectArray& visited_factories =
284 GrowableObjectArray::Handle(GrowableObjectArray::New()); 284 GrowableObjectArray::Handle(GrowableObjectArray::New());
285 ResolveRedirectingFactoryTarget(cls, factory, visited_factories); 285 ResolveRedirectingFactoryTarget(cls, factory, visited_factories);
286 } 286 }
287 if (factory.is_const()) { 287 if (factory.is_const()) {
288 type = factory.RedirectionType(); 288 type = factory.RedirectionType();
289 if (type.IsMalformed()) { 289 if (type.IsMalformedOrMalbounded()) {
290 ReportError(Error::Handle(type.malformed_error())); 290 ReportError(Error::Handle(type.error()));
291 }
292 Error& error = Error::Handle();
293 if (type.IsMalboundedWithError(&error)) {
294 ReportError(error);
295 } 291 }
296 } 292 }
297 } 293 }
298 } 294 }
299 295
300 296
301 void ClassFinalizer::ResolveRedirectingFactoryTarget( 297 void ClassFinalizer::ResolveRedirectingFactoryTarget(
302 const Class& cls, 298 const Class& cls,
303 const Function& factory, 299 const Function& factory,
304 const GrowableObjectArray& visited_factories) { 300 const GrowableObjectArray& visited_factories) {
305 ASSERT(factory.IsRedirectingFactory()); 301 ASSERT(factory.IsRedirectingFactory());
306 302
307 // Check for redirection cycle. 303 // Check for redirection cycle.
308 for (intptr_t i = 0; i < visited_factories.Length(); i++) { 304 for (intptr_t i = 0; i < visited_factories.Length(); i++) {
309 if (visited_factories.At(i) == factory.raw()) { 305 if (visited_factories.At(i) == factory.raw()) {
310 // A redirection cycle is reported as a compile-time error. 306 // A redirection cycle is reported as a compile-time error.
311 const Script& script = Script::Handle(cls.script()); 307 const Script& script = Script::Handle(cls.script());
312 ReportError(Error::Handle(), // No previous error. 308 ReportError(Error::Handle(), // No previous error.
313 script, factory.token_pos(), 309 script, factory.token_pos(),
314 "factory '%s' illegally redirects to itself", 310 "factory '%s' illegally redirects to itself",
315 String::Handle(factory.name()).ToCString()); 311 String::Handle(factory.name()).ToCString());
316 } 312 }
317 } 313 }
318 visited_factories.Add(factory); 314 visited_factories.Add(factory);
319 315
320 // Check if target is already resolved. 316 // Check if target is already resolved.
321 Type& type = Type::Handle(factory.RedirectionType()); 317 Type& type = Type::Handle(factory.RedirectionType());
322 Function& target = Function::Handle(factory.RedirectionTarget()); 318 Function& target = Function::Handle(factory.RedirectionTarget());
323 if (type.IsMalformed() || (type.IsResolved() && type.IsMalbounded())) { 319 if (type.IsMalformedOrMalbounded()) {
324 // Already resolved to a malformed or malbounded type. Will throw on usage. 320 // Already resolved to a malformed or malbounded type. Will throw on usage.
325 ASSERT(target.IsNull()); 321 ASSERT(target.IsNull());
326 return; 322 return;
327 } 323 }
328 if (!target.IsNull()) { 324 if (!target.IsNull()) {
329 // Already resolved. 325 // Already resolved.
330 return; 326 return;
331 } 327 }
332 328
333 // Target is not resolved yet. 329 // Target is not resolved yet.
334 if (FLAG_trace_class_finalization) { 330 if (FLAG_trace_class_finalization) {
335 OS::Print("Resolving redirecting factory: %s\n", 331 OS::Print("Resolving redirecting factory: %s\n",
336 String::Handle(factory.name()).ToCString()); 332 String::Handle(factory.name()).ToCString());
337 } 333 }
338 ResolveType(cls, type, kCanonicalize); 334 ResolveType(cls, type, kCanonicalize);
339 type ^= FinalizeType(cls, type, kCanonicalize); 335 type ^= FinalizeType(cls, type, kCanonicalize);
340 factory.SetRedirectionType(type); 336 factory.SetRedirectionType(type);
341 if (type.IsMalformed() || type.IsMalbounded()) { 337 if (type.IsMalformedOrMalbounded()) {
342 ASSERT(factory.RedirectionTarget() == Function::null()); 338 ASSERT(factory.RedirectionTarget() == Function::null());
343 return; 339 return;
344 } 340 }
345 ASSERT(!type.IsTypeParameter()); // Resolved in parser. 341 ASSERT(!type.IsTypeParameter()); // Resolved in parser.
346 if (type.IsDynamicType()) { 342 if (type.IsDynamicType()) {
347 // Replace the type with a malformed type and compile a throw when called. 343 // Replace the type with a malformed type and compile a throw when called.
348 type = NewFinalizedMalformedType( 344 type = NewFinalizedMalformedType(
349 Error::Handle(), // No previous error. 345 Error::Handle(), // No previous error.
350 Script::Handle(cls.script()), 346 Script::Handle(cls.script()),
351 factory.token_pos(), 347 factory.token_pos(),
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 // The finalized type argument vector needs num_type_arguments types. 803 // The finalized type argument vector needs num_type_arguments types.
808 const intptr_t num_type_arguments = type_class.NumTypeArguments(); 804 const intptr_t num_type_arguments = type_class.NumTypeArguments();
809 // The type class has num_type_parameters type parameters. 805 // The type class has num_type_parameters type parameters.
810 const intptr_t num_type_parameters = type_class.NumTypeParameters(); 806 const intptr_t num_type_parameters = type_class.NumTypeParameters();
811 807
812 // Initialize the type argument vector. 808 // Initialize the type argument vector.
813 // Check the number of parsed type arguments, if any. 809 // Check the number of parsed type arguments, if any.
814 // Specifying no type arguments indicates a raw type, which is not an error. 810 // Specifying no type arguments indicates a raw type, which is not an error.
815 // However, type parameter bounds are checked below, even for a raw type. 811 // However, type parameter bounds are checked below, even for a raw type.
816 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) { 812 if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
817 // Wrong number of type arguments. The type is malformed. 813 // Wrong number of type arguments. The type is mapped to the raw type.
818 if (FLAG_error_on_bad_type) { 814 if (FLAG_error_on_bad_type) {
819 const Script& script = Script::Handle(cls.script()); 815 const Script& script = Script::Handle(cls.script());
820 const String& type_class_name = String::Handle(type_class.Name()); 816 const String& type_class_name = String::Handle(type_class.Name());
821 ReportError(Error::Handle(), // No previous error. 817 ReportError(Error::Handle(), // No previous error.
822 script, parameterized_type.token_pos(), 818 script, parameterized_type.token_pos(),
823 "wrong number of type arguments for class '%s'", 819 "wrong number of type arguments for class '%s'",
824 type_class_name.ToCString()); 820 type_class_name.ToCString());
825 } 821 }
826 // Make the type raw and continue without reporting any error. 822 // Make the type raw and continue without reporting any error.
827 // A static warning should have been reported. 823 // A static warning should have been reported.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 // signature type, i.e. finalizing the result type and parameter types of the 908 // signature type, i.e. finalizing the result type and parameter types of the
913 // signature function of this signature type. 909 // signature function of this signature type.
914 // We do this after marking this type as finalized in order to allow a 910 // We do this after marking this type as finalized in order to allow a
915 // function type to refer to itself via its parameter types and result type. 911 // function type to refer to itself via its parameter types and result type.
916 if (type_class.IsSignatureClass()) { 912 if (type_class.IsSignatureClass()) {
917 // The class may be created while parsing a function body, after all 913 // The class may be created while parsing a function body, after all
918 // pending classes have already been finalized. 914 // pending classes have already been finalized.
919 FinalizeTypesInClass(type_class); 915 FinalizeTypesInClass(type_class);
920 } 916 }
921 917
922 // If a bound error occurred, return a BoundedType with a malformed bound. 918 // If a bound error occurred, mark the type as malbounded.
923 // The malformed bound will be ignored in production mode. 919 // The bound error will be ignored in production mode.
924 if (!bound_error.IsNull()) { 920 if (!bound_error.IsNull()) {
925 // No compile-time error during finalization. 921 // No compile-time error during finalization.
926 const String& parameterized_type_name = String::Handle( 922 const String& parameterized_type_name = String::Handle(
927 parameterized_type.UserVisibleName()); 923 parameterized_type.UserVisibleName());
928 const Type& malformed_bound = Type::Handle( 924 FinalizeMalboundedType(bound_error,
929 NewFinalizedMalformedType(bound_error, 925 Script::Handle(cls.script()),
930 Script::Handle(cls.script()), 926 parameterized_type,
931 parameterized_type.token_pos(), 927 "type '%s' has an out of bound type argument",
932 "type '%s' has an out of bound type argument", 928 parameterized_type_name.ToCString());
933 parameterized_type_name.ToCString()));
934 929
935 if (FLAG_trace_type_finalization) { 930 if (FLAG_trace_type_finalization) {
936 OS::Print("Done finalizing malbounded type '%s' with bound error: %s\n", 931 OS::Print("Done finalizing malbounded type '%s' with bound error: %s\n",
937 String::Handle(parameterized_type.Name()).ToCString(), 932 String::Handle(parameterized_type.Name()).ToCString(),
938 bound_error.ToCString()); 933 bound_error.ToCString());
939 } 934 }
940 935
941 return BoundedType::New(parameterized_type, 936 return parameterized_type.raw();;
942 malformed_bound,
943 TypeParameter::Handle());
944 } 937 }
945 938
946 if (FLAG_trace_type_finalization) { 939 if (FLAG_trace_type_finalization) {
947 OS::Print("Done finalizing type '%s' with %" Pd " type args\n", 940 OS::Print("Done finalizing type '%s' with %" Pd " type args\n",
948 String::Handle(parameterized_type.Name()).ToCString(), 941 String::Handle(parameterized_type.Name()).ToCString(),
949 parameterized_type.arguments() == AbstractTypeArguments::null() ? 942 parameterized_type.arguments() == AbstractTypeArguments::null() ?
950 0 : num_type_arguments); 943 0 : num_type_arguments);
951 } 944 }
952 945
953 if (finalization >= kCanonicalize) { 946 if (finalization >= kCanonicalize) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 class_name.ToCString(), 1149 class_name.ToCString(),
1157 name.ToCString(), 1150 name.ToCString(),
1158 super_class_name.ToCString()); 1151 super_class_name.ToCString());
1159 } 1152 }
1160 } 1153 }
1161 if (field.is_static() && (field.is_const() || field.is_final()) && 1154 if (field.is_static() && (field.is_const() || field.is_final()) &&
1162 (field.value() != Object::null()) && 1155 (field.value() != Object::null()) &&
1163 (field.value() != Object::sentinel().raw())) { 1156 (field.value() != Object::sentinel().raw())) {
1164 // The parser does not preset the value if the type is a type parameter or 1157 // The parser does not preset the value if the type is a type parameter or
1165 // is parameterized unless the value is null. 1158 // is parameterized unless the value is null.
1166 Error& malformed_error = Error::Handle(); 1159 Error& error = Error::Handle();
1167 if (type.IsMalformed()) { 1160 if (type.IsMalformedOrMalbounded()) {
1168 malformed_error = type.malformed_error(); 1161 error = type.error();
1169 } else { 1162 } else {
1170 ASSERT(type.IsInstantiated()); 1163 ASSERT(type.IsInstantiated());
1171 } 1164 }
1172 const Instance& const_value = Instance::Handle(field.value()); 1165 const Instance& const_value = Instance::Handle(field.value());
1173 if (!malformed_error.IsNull() || 1166 if (!error.IsNull() ||
1174 (!type.IsDynamicType() && 1167 (!type.IsDynamicType() &&
1175 !const_value.IsInstanceOf(type, 1168 !const_value.IsInstanceOf(type,
1176 AbstractTypeArguments::Handle(), 1169 AbstractTypeArguments::Handle(),
1177 &malformed_error))) { 1170 &error))) {
1178 if (FLAG_error_on_bad_type) { 1171 if (FLAG_error_on_bad_type) {
1179 const AbstractType& const_value_type = AbstractType::Handle( 1172 const AbstractType& const_value_type = AbstractType::Handle(
1180 const_value.GetType()); 1173 const_value.GetType());
1181 const String& const_value_type_name = String::Handle( 1174 const String& const_value_type_name = String::Handle(
1182 const_value_type.UserVisibleName()); 1175 const_value_type.UserVisibleName());
1183 const String& type_name = String::Handle(type.UserVisibleName()); 1176 const String& type_name = String::Handle(type.UserVisibleName());
1184 const Script& script = Script::Handle(cls.script()); 1177 const Script& script = Script::Handle(cls.script());
1185 ReportError(malformed_error, script, field.token_pos(), 1178 ReportError(error, script, field.token_pos(),
1186 "error initializing static %s field '%s': " 1179 "error initializing static %s field '%s': "
1187 "type '%s' is not a subtype of type '%s'", 1180 "type '%s' is not a subtype of type '%s'",
1188 field.is_const() ? "const" : "final", 1181 field.is_const() ? "const" : "final",
1189 name.ToCString(), 1182 name.ToCString(),
1190 const_value_type_name.ToCString(), 1183 const_value_type_name.ToCString(),
1191 type_name.ToCString()); 1184 type_name.ToCString());
1192 } else { 1185 } else {
1193 // Do not report an error yet, even in checked mode, since the field 1186 // Do not report an error yet, even in checked mode, since the field
1194 // may not actually be used. 1187 // may not actually be used.
1195 // Also, we may be generating a snapshot in production mode that will 1188 // Also, we may be generating a snapshot in production mode that will
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after
2403 // are lifted. 2396 // are lifted.
2404 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary(); 2397 const bool cls_belongs_to_core_lib = cls.library() == Library::CoreLibrary();
2405 2398
2406 // Resolve and check the super type and interfaces of cls. 2399 // Resolve and check the super type and interfaces of cls.
2407 visited->Add(cls_index); 2400 visited->Add(cls_index);
2408 AbstractType& interface = AbstractType::Handle(); 2401 AbstractType& interface = AbstractType::Handle();
2409 Class& interface_class = Class::Handle(); 2402 Class& interface_class = Class::Handle();
2410 2403
2411 // Resolve super type. Failures lead to a longjmp. 2404 // Resolve super type. Failures lead to a longjmp.
2412 ResolveType(cls, super_type, kCanonicalizeWellFormed); 2405 ResolveType(cls, super_type, kCanonicalizeWellFormed);
2413 if (super_type.IsMalformed()) { 2406 if (super_type.IsMalformedOrMalbounded()) {
2414 ReportError(Error::Handle(super_type.malformed_error())); 2407 ReportError(Error::Handle(super_type.error()));
2415 } 2408 }
2416 if (super_type.IsDynamicType()) { 2409 if (super_type.IsDynamicType()) {
2417 const Script& script = Script::Handle(cls.script()); 2410 const Script& script = Script::Handle(cls.script());
2418 ReportError(Error::Handle(), // No previous error. 2411 ReportError(Error::Handle(), // No previous error.
2419 script, cls.token_pos(), 2412 script, cls.token_pos(),
2420 "class '%s' may not extend 'dynamic'", 2413 "class '%s' may not extend 'dynamic'",
2421 String::Handle(cls.Name()).ToCString()); 2414 String::Handle(cls.Name()).ToCString());
2422 } 2415 }
2423 interface_class = super_type.type_class(); 2416 interface_class = super_type.type_class();
2424 if (interface_class.IsSignatureClass()) { 2417 if (interface_class.IsSignatureClass()) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2481 } 2474 }
2482 } 2475 }
2483 // Now resolve the super interfaces of the super type. 2476 // Now resolve the super interfaces of the super type.
2484 ResolveSuperTypeAndInterfaces(interface_class, visited); 2477 ResolveSuperTypeAndInterfaces(interface_class, visited);
2485 2478
2486 // Resolve interfaces. Failures lead to a longjmp. 2479 // Resolve interfaces. Failures lead to a longjmp.
2487 for (intptr_t i = 0; i < super_interfaces.Length(); i++) { 2480 for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
2488 interface ^= super_interfaces.At(i); 2481 interface ^= super_interfaces.At(i);
2489 ResolveType(cls, interface, kCanonicalizeWellFormed); 2482 ResolveType(cls, interface, kCanonicalizeWellFormed);
2490 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser. 2483 ASSERT(!interface.IsTypeParameter()); // Should be detected by parser.
2484 // A malbounded interface is only reported when involved in a type test.
2491 if (interface.IsMalformed()) { 2485 if (interface.IsMalformed()) {
2492 ReportError(Error::Handle(interface.malformed_error())); 2486 ReportError(Error::Handle(interface.error()));
2493 } 2487 }
2494 if (interface.IsDynamicType()) { 2488 if (interface.IsDynamicType()) {
2495 const Script& script = Script::Handle(cls.script()); 2489 const Script& script = Script::Handle(cls.script());
2496 ReportError(Error::Handle(), // No previous error. 2490 ReportError(Error::Handle(), // No previous error.
2497 script, cls.token_pos(), 2491 script, cls.token_pos(),
2498 "'dynamic' may not be used as interface"); 2492 "'dynamic' may not be used as interface");
2499 } 2493 }
2500 interface_class = interface.type_class(); 2494 interface_class = interface.type_class();
2501 if (interface_class.IsSignatureClass()) { 2495 if (interface_class.IsSignatureClass()) {
2502 const Script& script = Script::Handle(cls.script()); 2496 const Script& script = Script::Handle(cls.script());
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2615 const char* format, 2609 const char* format,
2616 va_list args) { 2610 va_list args) {
2617 LanguageError& error = LanguageError::Handle( 2611 LanguageError& error = LanguageError::Handle(
2618 LanguageError::NewFormattedV( 2612 LanguageError::NewFormattedV(
2619 prev_error, script, type.token_pos(), 2613 prev_error, script, type.token_pos(),
2620 LanguageError::kMalformedType, Heap::kOld, 2614 LanguageError::kMalformedType, Heap::kOld,
2621 format, args)); 2615 format, args));
2622 if (FLAG_error_on_bad_type) { 2616 if (FLAG_error_on_bad_type) {
2623 ReportError(error); 2617 ReportError(error);
2624 } 2618 }
2625 type.set_malformed_error(error); 2619 type.set_error(error);
2626 // Make the type raw, since it may not be possible to 2620 // Make the type raw, since it may not be possible to
2627 // properly finalize its type arguments. 2621 // properly finalize its type arguments.
2628 type.set_type_class(Class::Handle(Object::dynamic_class())); 2622 type.set_type_class(Class::Handle(Object::dynamic_class()));
2629 type.set_arguments(Object::null_abstract_type_arguments()); 2623 type.set_arguments(Object::null_abstract_type_arguments());
2630 if (!type.IsFinalized()) { 2624 if (!type.IsFinalized()) {
2631 type.SetIsFinalized(); 2625 type.SetIsFinalized();
2632 // Do not canonicalize malformed types, since they may not be resolved. 2626 // Do not canonicalize malformed types, since they may not be resolved.
2633 } else { 2627 } else {
2634 // The only case where the malformed type was already finalized is when its 2628 // The only case where the malformed type was already finalized is when its
2635 // type arguments are not within bounds. In that case, we have a prev_error. 2629 // type arguments are not within bounds. In that case, we have a prev_error.
(...skipping 26 matching lines...) Expand all
2662 const Script& script, 2656 const Script& script,
2663 const Type& type, 2657 const Type& type,
2664 const char* format, ...) { 2658 const char* format, ...) {
2665 va_list args; 2659 va_list args;
2666 va_start(args, format); 2660 va_start(args, format);
2667 ReportMalformedType(prev_error, script, type, format, args); 2661 ReportMalformedType(prev_error, script, type, format, args);
2668 va_end(args); 2662 va_end(args);
2669 } 2663 }
2670 2664
2671 2665
2666 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error,
2667 const Script& script,
2668 const Type& type,
2669 const char* format, ...) {
2670 va_list args;
2671 va_start(args, format);
2672 LanguageError& error = LanguageError::Handle(
2673 LanguageError::NewFormattedV(
2674 prev_error, script, type.token_pos(),
2675 LanguageError::kMalboundedType, Heap::kOld,
2676 format, args));
2677 va_end(args);
2678 if (FLAG_error_on_bad_type) {
2679 ReportError(error);
2680 }
2681 type.set_error(error);
2682 if (!type.IsFinalized()) {
2683 type.SetIsFinalized();
2684 // Do not canonicalize malbounded types.
2685 }
2686 }
2687
2688
2672 void ClassFinalizer::ReportError(const Error& error) { 2689 void ClassFinalizer::ReportError(const Error& error) {
2673 Isolate::Current()->long_jump_base()->Jump(1, error); 2690 Isolate::Current()->long_jump_base()->Jump(1, error);
2674 UNREACHABLE(); 2691 UNREACHABLE();
2675 } 2692 }
2676 2693
2677 2694
2678 void ClassFinalizer::ReportError(const Error& prev_error, 2695 void ClassFinalizer::ReportError(const Error& prev_error,
2679 const Script& script, 2696 const Script& script,
2680 intptr_t token_pos, 2697 intptr_t token_pos,
2681 const char* format, ...) { 2698 const char* format, ...) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2744 expected_name ^= String::New("_offset"); 2761 expected_name ^= String::New("_offset");
2745 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name)); 2762 ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
2746 field ^= fields_array.At(2); 2763 field ^= fields_array.At(2);
2747 ASSERT(field.Offset() == TypedDataView::length_offset()); 2764 ASSERT(field.Offset() == TypedDataView::length_offset());
2748 name ^= field.name(); 2765 name ^= field.name();
2749 ASSERT(name.Equals("length")); 2766 ASSERT(name.Equals("length"));
2750 #endif 2767 #endif
2751 } 2768 }
2752 2769
2753 } // namespace dart 2770 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.h ('k') | runtime/vm/code_generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698