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

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/js_rti.dart

Issue 803103004: Revert "dart2js: put all type-test related properties on the prototype and not on the constructor." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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
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 /** 5 /**
6 * This part contains helpers for supporting runtime type information. 6 * This part contains helpers for supporting runtime type information.
7 * 7 *
8 * The helper use a mixture of Dart and JavaScript objects. To indicate which is 8 * The helper use a mixture of Dart and JavaScript objects. To indicate which is
9 * used where we adopt the scheme of using explicit type annotation for Dart 9 * used where we adopt the scheme of using explicit type annotation for Dart
10 * objects and 'var' or omitted return type for JavaScript objects. 10 * objects and 'var' or omitted return type for JavaScript objects.
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 * See the comment in the beginning of this file for a description of type 383 * See the comment in the beginning of this file for a description of type
384 * representations. 384 * representations.
385 */ 385 */
386 bool checkSubtypeOfRuntimeType(o, t) { 386 bool checkSubtypeOfRuntimeType(o, t) {
387 if (o == null) return isSupertypeOfNull(t); 387 if (o == null) return isSupertypeOfNull(t);
388 if (t == null) return true; 388 if (t == null) return true;
389 // Get the runtime type information from the object here, because we may 389 // Get the runtime type information from the object here, because we may
390 // overwrite o with the interceptor below. 390 // overwrite o with the interceptor below.
391 var rti = getRuntimeTypeInfo(o); 391 var rti = getRuntimeTypeInfo(o);
392 o = getInterceptor(o); 392 o = getInterceptor(o);
393 var type = JS('', '#.constructor', o); 393 // We can use the object as its own type representation because we install
394 var type;
394 if (rti != null) { 395 if (rti != null) {
395 // If the type has type variables (that is, `rti != null`), make a copy of 396 // If the type has type variables (that is, `rti != null`), make a copy of
396 // the type arguments and insert [o] in the first position to create a 397 // the type arguments and insert [o] in the first position to create a
397 // compound type representation. 398 // compound type representation.
398 rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy. 399 type = JS('JSExtendableArray', '#.slice()', rti);
399 JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0. 400 JS('', '#.splice(0, 0, #)', type, o);
400 type = rti; 401 } else {
401 } else if (hasField(t, '${JS_FUNCTION_TYPE_TAG()}')) { 402 // Use the object as representation of the raw type.
402 // Functions are treated specially and have their type information stored 403 type = o;
403 // directly in the instance.
404 var signatureName =
405 '${JS_OPERATOR_IS_PREFIX()}_${getField(t, JS_FUNCTION_TYPE_TAG())}';
406 if (hasField(o, signatureName)) return true;
407 var targetSignatureFunction = getField(o, '${JS_SIGNATURE_NAME()}');
408 if (targetSignatureFunction == null) return false;
409 type = invokeOn(targetSignatureFunction, o, null);
410 return isFunctionSubtype(type, t);
411 } 404 }
412 return isSubtype(type, t); 405 return isSubtype(type, t);
413 } 406 }
414 407
415 Object subtypeOfRuntimeTypeCast(Object object, var type) { 408 Object subtypeOfRuntimeTypeCast(Object object, var type) {
416 if (object != null && !checkSubtypeOfRuntimeType(object, type)) { 409 if (object != null && !checkSubtypeOfRuntimeType(object, type)) {
417 String actualType = Primitives.objectTypeName(object); 410 String actualType = Primitives.objectTypeName(object);
418 throw new CastErrorImplementation(actualType, runtimeTypeToString(type)); 411 throw new CastErrorImplementation(actualType, runtimeTypeToString(type));
419 } 412 }
420 return object; 413 return object;
(...skipping 13 matching lines...) Expand all
434 getArguments(var type) { 427 getArguments(var type) {
435 return isJsArray(type) ? JS('var', r'#.slice(1)', type) : null; 428 return isJsArray(type) ? JS('var', r'#.slice(1)', type) : null;
436 } 429 }
437 430
438 /** 431 /**
439 * Checks whether the type represented by the type representation [s] is a 432 * Checks whether the type represented by the type representation [s] is a
440 * subtype of the type represented by the type representation [t]. 433 * subtype of the type represented by the type representation [t].
441 * 434 *
442 * See the comment in the beginning of this file for a description of type 435 * See the comment in the beginning of this file for a description of type
443 * representations. 436 * representations.
444 *
445 * The arguments [s] and [t] must be types, usually represented by the
446 * constructor of the class, or an array (for generic types).
447 */ 437 */
448 bool isSubtype(var s, var t) { 438 bool isSubtype(var s, var t) {
449 // Subtyping is reflexive. 439 // Subtyping is reflexive.
450 if (isIdentical(s, t)) return true; 440 if (isIdentical(s, t)) return true;
451 // If either type is dynamic, [s] is a subtype of [t]. 441 // If either type is dynamic, [s] is a subtype of [t].
452 if (s == null || t == null) return true; 442 if (s == null || t == null) return true;
453 if (hasField(t, '${JS_FUNCTION_TYPE_TAG()}')) { 443 if (hasField(t, '${JS_FUNCTION_TYPE_TAG()}')) {
444 if (hasNoField(s, '${JS_FUNCTION_TYPE_TAG()}')) {
445 var signatureName =
446 '${JS_OPERATOR_IS_PREFIX()}_${getField(t, JS_FUNCTION_TYPE_TAG())}';
447 if (hasField(s, signatureName)) return true;
448 var targetSignatureFunction = getField(s, '${JS_SIGNATURE_NAME()}');
449 if (targetSignatureFunction == null) return false;
450 s = invokeOn(targetSignatureFunction, s, null);
451 }
454 return isFunctionSubtype(s, t); 452 return isFunctionSubtype(s, t);
455 } 453 }
456 // Check function types against the Function class. 454 // Check function types against the Function class.
457 if (hasField(s, '${JS_FUNCTION_TYPE_TAG()}')) { 455 if (getConstructorName(t) == JS_FUNCTION_CLASS_NAME() &&
458 return getConstructorName(t) == JS_FUNCTION_CLASS_NAME(); 456 hasField(s, '${JS_FUNCTION_TYPE_TAG()}')) {
457 return true;
459 } 458 }
460
461 // Get the object describing the class and check for the subtyping flag 459 // Get the object describing the class and check for the subtyping flag
462 // constructed from the type of [t]. 460 // constructed from the type of [t].
463 var typeOfS = isJsArray(s) ? getIndex(s, 0) : s; 461 var typeOfS = isJsArray(s) ? getIndex(s, 0) : s;
464 var typeOfT = isJsArray(t) ? getIndex(t, 0) : t; 462 var typeOfT = isJsArray(t) ? getIndex(t, 0) : t;
465 // Check for a subtyping flag. 463 // Check for a subtyping flag.
466 var name = runtimeTypeToString(typeOfT); 464 var name = runtimeTypeToString(typeOfT);
467 // Get the necessary substitution of the type arguments, if there is one. 465 // Get the necessary substitution of the type arguments, if there is one.
468 var substitution; 466 var substitution;
469 if (isNotIdentical(typeOfT, typeOfS)) { 467 if (isNotIdentical(typeOfT, typeOfS)) {
470 var test = '${JS_OPERATOR_IS_PREFIX()}${name}'; 468 var test = '${JS_OPERATOR_IS_PREFIX()}${name}';
471 var typeOfSPrototype = JS('', '#.prototype', typeOfS); 469 if (hasNoField(typeOfS, test)) return false;
472 if (hasNoField(typeOfSPrototype, test)) return false;
473 var field = '${JS_OPERATOR_AS_PREFIX()}${runtimeTypeToString(typeOfT)}'; 470 var field = '${JS_OPERATOR_AS_PREFIX()}${runtimeTypeToString(typeOfT)}';
474 substitution = getField(typeOfSPrototype, field); 471 substitution = getField(typeOfS, field);
475 } 472 }
476 // The class of [s] is a subclass of the class of [t]. If [s] has no type 473 // The class of [s] is a subclass of the class of [t]. If [s] has no type
477 // arguments and no substitution, it is used as raw type. If [t] has no 474 // arguments and no substitution, it is used as raw type. If [t] has no
478 // type arguments, it used as a raw type. In both cases, [s] is a subtype 475 // type arguments, it used as a raw type. In both cases, [s] is a subtype
479 // of [t]. 476 // of [t].
480 if ((!isJsArray(s) && substitution == null) || !isJsArray(t)) { 477 if ((!isJsArray(s) && substitution == null) || !isJsArray(t)) {
481 return true; 478 return true;
482 } 479 }
483 // Recursively check the type arguments. 480 // Recursively check the type arguments.
484 return checkArguments(substitution, getArguments(s), getArguments(t)); 481 return checkArguments(substitution, getArguments(s), getArguments(t));
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 * `null` and `undefined` (which we can avoid). 676 * `null` and `undefined` (which we can avoid).
680 */ 677 */
681 bool isIdentical(var s, var t) => JS('bool', '# === #', s, t); 678 bool isIdentical(var s, var t) => JS('bool', '# === #', s, t);
682 679
683 /** 680 /**
684 * Returns `true` if the JavaScript values [s] and [t] are not identical. We use 681 * Returns `true` if the JavaScript values [s] and [t] are not identical. We use
685 * this helper instead of [identical] because `identical` needs to merge 682 * this helper instead of [identical] because `identical` needs to merge
686 * `null` and `undefined` (which we can avoid). 683 * `null` and `undefined` (which we can avoid).
687 */ 684 */
688 bool isNotIdentical(var s, var t) => JS('bool', '# !== #', s, t); 685 bool isNotIdentical(var s, var t) => JS('bool', '# !== #', s, t);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698