mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:27:39 +00:00
dart2js cps: Type casts and related changes to type propagation.
We now optimize type casts that always fail or always pass. Type propagation has been refactored a bit to make this work. A new IR node Unreachable has been added. This is an node that is known to be unreachable and is ultimately compiled to an empty statement. BUG= R=karlklose@google.com Review URL: https://codereview.chromium.org//1153603006
This commit is contained in:
parent
1aae7d282e
commit
d01d394af7
|
@ -2407,11 +2407,18 @@ class JsIrBuilder extends IrBuilder {
|
|||
<ir.Primitive>[message]);
|
||||
}
|
||||
|
||||
List<ir.Primitive> typeArguments = const <ir.Primitive>[];
|
||||
if (type is GenericType && type.typeArguments.isNotEmpty) {
|
||||
typeArguments = type.typeArguments.map(buildTypeExpression).toList();
|
||||
} else if (type is TypeVariableType) {
|
||||
typeArguments = <ir.Primitive>[buildTypeVariableAccess(type)];
|
||||
}
|
||||
|
||||
if (isTypeTest) {
|
||||
// For type tests, we must treat specially the rare cases where `null`
|
||||
// satisfies the test (which otherwise never satisfies a type test).
|
||||
// This is not an optimization: the TypeOperator assumes that `null`
|
||||
// cannot satisfy the type test.
|
||||
// cannot satisfy the type test unless the type is a type variable.
|
||||
if (type.isObject || type.isDynamic) {
|
||||
// `x is Object` and `x is dynamic` are always true, even if x is null.
|
||||
return buildBooleanConstant(true);
|
||||
|
@ -2420,17 +2427,11 @@ class JsIrBuilder extends IrBuilder {
|
|||
// `x is Null` is true if and only if x is null.
|
||||
return addPrimitive(new ir.Identical(value, buildNullConstant()));
|
||||
}
|
||||
return addPrimitive(new ir.TypeTest(value, type, typeArguments));
|
||||
} else {
|
||||
return _continueWithExpression(
|
||||
(k) => new ir.TypeCast(value, type, typeArguments, k));
|
||||
}
|
||||
List<ir.Primitive> typeArguments = const <ir.Primitive>[];
|
||||
if (type is GenericType && type.typeArguments.isNotEmpty) {
|
||||
typeArguments = type.typeArguments.map(buildTypeExpression).toList();
|
||||
} else if (type is TypeVariableType) {
|
||||
typeArguments = <ir.Primitive>[buildTypeVariableAccess(type)];
|
||||
}
|
||||
ir.Primitive check = _continueWithExpression(
|
||||
(k) => new ir.TypeOperator(value,
|
||||
type, typeArguments, k, isTypeTest: isTypeTest));
|
||||
return check;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -2810,13 +2810,11 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
|
|||
/// - Replace [ir.LetPrim] binding a [ir.NonTailThrow] with a [ir.Throw]
|
||||
/// expression.
|
||||
class CleanupPass extends ir.RecursiveVisitor {
|
||||
RemovalVisitor _remover = new RemovalVisitor();
|
||||
|
||||
ir.Expression replacementFor(ir.Expression expression) {
|
||||
if (expression != null && expression is ir.LetPrim) {
|
||||
ir.Primitive primitive = expression.primitive;
|
||||
if (primitive is ir.NonTailThrow) {
|
||||
_remover.visit(expression);
|
||||
ir.RemovalVisitor.remove(expression);
|
||||
return new ir.Throw(primitive.value.definition);
|
||||
}
|
||||
}
|
||||
|
@ -2859,10 +2857,3 @@ class CleanupPass extends ir.RecursiveVisitor {
|
|||
node.body = replacementFor(node.body);
|
||||
}
|
||||
}
|
||||
|
||||
/// Visit a just-deleted subterm and unlink all [Reference]s in it.
|
||||
class RemovalVisitor extends ir.RecursiveVisitor {
|
||||
processReference(ir.Reference reference) {
|
||||
reference.unlink();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ abstract class Node {
|
|||
/// that can be obtained without side-effects, divergence, or throwing
|
||||
/// exceptions can be built using a [LetPrim].
|
||||
abstract class Expression extends Node {
|
||||
InteriorNode get parent; // Only InteriorNodes may contain expressions.
|
||||
|
||||
Expression plug(Expression expr) => throw 'impossible';
|
||||
}
|
||||
|
||||
|
@ -357,10 +359,47 @@ class InvokeConstructor extends Expression implements Invoke {
|
|||
accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
|
||||
}
|
||||
|
||||
// TODO(asgerf): Make a Primitive for "is" and an Expression for "as".
|
||||
/// An "is" type test.
|
||||
///
|
||||
/// Returns `true` if [value] not `null` and is an instance of [type].
|
||||
///
|
||||
/// [type] must not be the [Object], `dynamic` or [Null] types (though it might
|
||||
/// be a type variable containing one of these types). This design is chosen
|
||||
/// to simplify code generation for type tests.
|
||||
class TypeTest extends Primitive {
|
||||
Reference<Primitive> value;
|
||||
final DartType type;
|
||||
|
||||
/// An "as" cast or an "is" check.
|
||||
class TypeOperator extends Expression {
|
||||
/// If [type] is an [InterfaceType], this holds the internal representation of
|
||||
/// the type arguments to [type]. Since these may reference type variables
|
||||
/// from the enclosing class, they are not constant.
|
||||
///
|
||||
/// If [type] is a [TypeVariableType], this is a singleton list with
|
||||
/// the internal representation of the type held in that type variable.
|
||||
///
|
||||
/// Otherwise the list is empty.
|
||||
final List<Reference<Primitive>> typeArguments;
|
||||
|
||||
TypeTest(Primitive value,
|
||||
this.type,
|
||||
List<Primitive> typeArguments)
|
||||
: this.value = new Reference<Primitive>(value),
|
||||
this.typeArguments = _referenceList(typeArguments);
|
||||
|
||||
accept(Visitor visitor) => visitor.visitTypeTest(this);
|
||||
}
|
||||
|
||||
/// An "as" type cast.
|
||||
///
|
||||
/// If [value] is `null` or is an instance of [type], [continuation] is invoked
|
||||
/// with [value] as argument. Otherwise, a [CastError] is thrown.
|
||||
///
|
||||
/// Discussion:
|
||||
/// The parameter to [continuation] is redundant since it will always equal
|
||||
/// [value], which is typically in scope in the continuation. However, it might
|
||||
/// simplify type propagation, since a better type can be computed for the
|
||||
/// continuation parameter without needing flow-sensitive analysis.
|
||||
class TypeCast extends Expression {
|
||||
Reference<Primitive> value;
|
||||
final DartType type;
|
||||
|
||||
|
@ -374,22 +413,16 @@ class TypeOperator extends Expression {
|
|||
/// Otherwise the list is empty.
|
||||
final List<Reference<Primitive>> typeArguments;
|
||||
final Reference<Continuation> continuation;
|
||||
final bool isTypeTest;
|
||||
|
||||
TypeOperator(Primitive value,
|
||||
this.type,
|
||||
List<Primitive> typeArguments,
|
||||
Continuation cont,
|
||||
{bool this.isTypeTest})
|
||||
TypeCast(Primitive value,
|
||||
this.type,
|
||||
List<Primitive> typeArguments,
|
||||
Continuation cont)
|
||||
: this.value = new Reference<Primitive>(value),
|
||||
this.typeArguments = _referenceList(typeArguments),
|
||||
this.continuation = new Reference<Continuation>(cont) {
|
||||
assert(isTypeTest != null);
|
||||
}
|
||||
this.continuation = new Reference<Continuation>(cont);
|
||||
|
||||
bool get isTypeCast => !isTypeTest;
|
||||
|
||||
accept(Visitor visitor) => visitor.visitTypeOperator(this);
|
||||
accept(Visitor visitor) => visitor.visitTypeCast(this);
|
||||
}
|
||||
|
||||
/// Invoke [toString] on each argument and concatenate the results.
|
||||
|
@ -439,6 +472,14 @@ class NonTailThrow extends Primitive {
|
|||
accept(Visitor visitor) => visitor.visitNonTailThrow(this);
|
||||
}
|
||||
|
||||
/// An expression that is known to be unreachable.
|
||||
///
|
||||
/// This can be placed as the body of a call continuation, when the caller is
|
||||
/// known never to invoke it, e.g. because the calling expression always throws.
|
||||
class Unreachable extends Expression {
|
||||
accept(Visitor visitor) => visitor.visitUnreachable(this);
|
||||
}
|
||||
|
||||
/// Gets the value from a [MutableVariable].
|
||||
///
|
||||
/// [MutableVariable]s can be seen as ref cells that are not first-class
|
||||
|
@ -495,6 +536,14 @@ class InvokeContinuation extends Expression {
|
|||
if (isRecursive) cont.isRecursive = true;
|
||||
}
|
||||
|
||||
/// Build a one-argument InvokeContinuation using existing reference objects.
|
||||
///
|
||||
/// This is useful for converting call continuations to local continuations.
|
||||
InvokeContinuation.fromCall(this.continuation,
|
||||
Reference<Primitive> argument)
|
||||
: arguments = <Reference<Primitive>>[argument],
|
||||
isRecursive = false;
|
||||
|
||||
/// A continuation invocation whose target and arguments will be filled
|
||||
/// in later.
|
||||
///
|
||||
|
@ -875,11 +924,12 @@ abstract class Visitor<T> {
|
|||
T visitThrow(Throw node);
|
||||
T visitRethrow(Rethrow node);
|
||||
T visitBranch(Branch node);
|
||||
T visitTypeOperator(TypeOperator node);
|
||||
T visitTypeCast(TypeCast node);
|
||||
T visitSetMutableVariable(SetMutableVariable node);
|
||||
T visitSetStatic(SetStatic node);
|
||||
T visitGetLazyStatic(GetLazyStatic node);
|
||||
T visitSetField(SetField node);
|
||||
T visitUnreachable(Unreachable node);
|
||||
|
||||
// Definitions.
|
||||
T visitLiteralList(LiteralList node);
|
||||
|
@ -901,6 +951,7 @@ abstract class Visitor<T> {
|
|||
T visitReadTypeVariable(ReadTypeVariable node);
|
||||
T visitTypeExpression(TypeExpression node);
|
||||
T visitCreateInvocationMirror(CreateInvocationMirror node);
|
||||
T visitTypeTest(TypeTest node);
|
||||
|
||||
// Conditions.
|
||||
T visitIsTrue(IsTrue node);
|
||||
|
@ -1018,14 +1069,21 @@ class RecursiveVisitor implements Visitor {
|
|||
visit(node.condition);
|
||||
}
|
||||
|
||||
processTypeOperator(TypeOperator node) {}
|
||||
visitTypeOperator(TypeOperator node) {
|
||||
processTypeOperator(node);
|
||||
processTypeCast(TypeCast node) {}
|
||||
visitTypeCast(TypeCast node) {
|
||||
processTypeCast(node);
|
||||
processReference(node.continuation);
|
||||
processReference(node.value);
|
||||
node.typeArguments.forEach(processReference);
|
||||
}
|
||||
|
||||
processTypeTest(TypeTest node) {}
|
||||
visitTypeTest(TypeTest node) {
|
||||
processTypeTest(node);
|
||||
processReference(node.value);
|
||||
node.typeArguments.forEach(processReference);
|
||||
}
|
||||
|
||||
processSetMutableVariable(SetMutableVariable node) {}
|
||||
visitSetMutableVariable(SetMutableVariable node) {
|
||||
processSetMutableVariable(node);
|
||||
|
@ -1175,4 +1233,22 @@ class RecursiveVisitor implements Visitor {
|
|||
processCreateInvocationMirror(node);
|
||||
node.arguments.forEach(processReference);
|
||||
}
|
||||
|
||||
processUnreachable(Unreachable node) {}
|
||||
visitUnreachable(Unreachable node) {
|
||||
processUnreachable(node);
|
||||
}
|
||||
}
|
||||
|
||||
/// Visit a just-deleted subterm and unlink all [Reference]s in it.
|
||||
class RemovalVisitor extends RecursiveVisitor {
|
||||
const RemovalVisitor();
|
||||
|
||||
processReference(Reference reference) {
|
||||
reference.unlink();
|
||||
}
|
||||
|
||||
static void remove(Node node) {
|
||||
(const RemovalVisitor()).visit(node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,6 +202,10 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
|
|||
return '$indentation(Branch $condition $trueCont $falseCont)';
|
||||
}
|
||||
|
||||
String visitUnreachable(Unreachable node) {
|
||||
return '$indentation(Unreachable)';
|
||||
}
|
||||
|
||||
String visitConstant(Constant node) {
|
||||
String value = node.value.accept(new ConstantStringifier(), null);
|
||||
return '(Constant $value)';
|
||||
|
@ -229,13 +233,17 @@ class SExpressionStringifier extends Indentation implements Visitor<String> {
|
|||
'$value\n$body)';
|
||||
}
|
||||
|
||||
String visitTypeOperator(TypeOperator node) {
|
||||
String visitTypeCast(TypeCast node) {
|
||||
String value = access(node.value);
|
||||
String cont = access(node.continuation);
|
||||
String operator = node.isTypeTest ? 'is' : 'as';
|
||||
String typeArguments = node.typeArguments.map(access).join(' ');
|
||||
return '$indentation(TypeOperator $operator $value ${node.type} '
|
||||
'($typeArguments) $cont)';
|
||||
return '$indentation(TypeCast $value ${node.type} ($typeArguments) $cont)';
|
||||
}
|
||||
|
||||
String visitTypeTest(TypeTest node) {
|
||||
String value = access(node.value);
|
||||
String typeArguments = node.typeArguments.map(access).join(' ');
|
||||
return '(TypeTest $value ${node.type} ($typeArguments))';
|
||||
}
|
||||
|
||||
String visitLiteralList(LiteralList node) {
|
||||
|
|
|
@ -193,6 +193,11 @@ class IRTracer extends TracerUtil implements cps_ir.Visitor {
|
|||
printStmt(dummy, "Rethrow");
|
||||
}
|
||||
|
||||
visitUnreachable(cps_ir.Unreachable node) {
|
||||
String dummy = names.name(node);
|
||||
printStmt(dummy, 'Unreachable');
|
||||
}
|
||||
|
||||
visitLiteralList(cps_ir.LiteralList node) {
|
||||
String dummy = names.name(node);
|
||||
String values = node.values.map(formatReference).join(', ');
|
||||
|
@ -210,13 +215,12 @@ class IRTracer extends TracerUtil implements cps_ir.Visitor {
|
|||
printStmt(dummy, "LiteralMap (${entries.join(', ')})");
|
||||
}
|
||||
|
||||
visitTypeOperator(cps_ir.TypeOperator node) {
|
||||
visitTypeCast(cps_ir.TypeCast node) {
|
||||
String dummy = names.name(node);
|
||||
String operator = node.isTypeTest ? 'is' : 'as';
|
||||
List<String> entries = new List<String>();
|
||||
String value = formatReference(node.value);
|
||||
String args = node.typeArguments.map(formatReference).join(', ');
|
||||
String kont = formatReference(node.continuation);
|
||||
printStmt(dummy, "TypeOperator ($operator $value ${node.type}) $kont");
|
||||
printStmt(dummy, "TypeCast ($value ${node.type} ($args)) $kont");
|
||||
}
|
||||
|
||||
visitInvokeContinuation(cps_ir.InvokeContinuation node) {
|
||||
|
@ -361,6 +365,12 @@ class IRTracer extends TracerUtil implements cps_ir.Visitor {
|
|||
String args = node.arguments.map(formatReference).join(', ');
|
||||
return "CreateInvocationMirror(${node.selector.name}, $args)";
|
||||
}
|
||||
|
||||
visitTypeTest(cps_ir.TypeTest node) {
|
||||
String value = formatReference(node.value);
|
||||
String args = node.typeArguments.map(formatReference).join(', ');
|
||||
return "TypeTest ($value ${node.type} ($args))";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -497,6 +507,9 @@ class BlockCollector implements cps_ir.Visitor {
|
|||
visitRethrow(cps_ir.Rethrow exp) {
|
||||
}
|
||||
|
||||
visitUnreachable(cps_ir.Unreachable node) {
|
||||
}
|
||||
|
||||
visitSetMutableVariable(cps_ir.SetMutableVariable exp) {
|
||||
visit(exp.body);
|
||||
}
|
||||
|
@ -524,7 +537,7 @@ class BlockCollector implements cps_ir.Visitor {
|
|||
}
|
||||
}
|
||||
|
||||
visitTypeOperator(cps_ir.TypeOperator exp) {
|
||||
visitTypeCast(cps_ir.TypeCast exp) {
|
||||
addEdgeToContinuation(exp.continuation);
|
||||
}
|
||||
|
||||
|
@ -603,4 +616,8 @@ class BlockCollector implements cps_ir.Visitor {
|
|||
visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
|
||||
unexpectedNode(node);
|
||||
}
|
||||
|
||||
visitTypeTest(cps_ir.TypeTest node) {
|
||||
unexpectedNode(node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -562,12 +562,17 @@ class ParentVisitor extends RecursiveVisitor {
|
|||
node.falseContinuation.parent = node;
|
||||
}
|
||||
|
||||
processTypeOperator(TypeOperator node) {
|
||||
processTypeCast(TypeCast node) {
|
||||
node.typeArguments.forEach((Reference ref) => ref.parent = node);
|
||||
node.continuation.parent = node;
|
||||
node.value.parent = node;
|
||||
}
|
||||
|
||||
processTypeTest(TypeTest node) {
|
||||
node.typeArguments.forEach((Reference ref) => ref.parent = node);
|
||||
node.value.parent = node;
|
||||
}
|
||||
|
||||
processSetMutableVariable(SetMutableVariable node) {
|
||||
node.variable.parent = node;
|
||||
node.body.parent = node;
|
||||
|
|
|
@ -25,6 +25,7 @@ abstract class TypeSystem<T> {
|
|||
T get functionType;
|
||||
T get boolType;
|
||||
T get intType;
|
||||
T get numType;
|
||||
T get stringType;
|
||||
T get listType;
|
||||
T get mapType;
|
||||
|
@ -44,6 +45,8 @@ abstract class TypeSystem<T> {
|
|||
bool isDefinitelyBool(T type);
|
||||
|
||||
bool isDefinitelyNotNull(T type);
|
||||
|
||||
AbstractBool isSubtypeOf(T value, types.DartType type, {bool allowNull});
|
||||
}
|
||||
|
||||
class UnitTypeSystem implements TypeSystem<String> {
|
||||
|
@ -53,6 +56,7 @@ class UnitTypeSystem implements TypeSystem<String> {
|
|||
get dynamicType => UNIT;
|
||||
get functionType => UNIT;
|
||||
get intType => UNIT;
|
||||
get numType => UNIT;
|
||||
get listType => UNIT;
|
||||
get mapType => UNIT;
|
||||
get stringType => UNIT;
|
||||
|
@ -67,15 +71,23 @@ class UnitTypeSystem implements TypeSystem<String> {
|
|||
exact(_) => UNIT;
|
||||
getTypeOf(_) => UNIT;
|
||||
|
||||
bool areDisjoint(String leftType, String rightType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isDefinitelyBool(_) => false;
|
||||
|
||||
bool isDefinitelyNotNull(_) => false;
|
||||
|
||||
bool areDisjoint(String leftType, String rightType) {
|
||||
return false;
|
||||
AbstractBool isSubtypeOf(value, type, {bool allowNull}) {
|
||||
return AbstractBool.Maybe;
|
||||
}
|
||||
}
|
||||
|
||||
enum AbstractBool {
|
||||
True, False, Maybe, Nothing
|
||||
}
|
||||
|
||||
class TypeMaskSystem implements TypeSystem<TypeMask> {
|
||||
final TypesTask inferrer;
|
||||
final ClassWorld classWorld;
|
||||
|
@ -85,6 +97,7 @@ class TypeMaskSystem implements TypeSystem<TypeMask> {
|
|||
TypeMask get functionType => inferrer.functionType;
|
||||
TypeMask get boolType => inferrer.boolType;
|
||||
TypeMask get intType => inferrer.intType;
|
||||
TypeMask get numType => inferrer.numType;
|
||||
TypeMask get stringType => inferrer.stringType;
|
||||
TypeMask get listType => inferrer.listType;
|
||||
TypeMask get mapType => inferrer.mapType;
|
||||
|
@ -140,6 +153,149 @@ class TypeMaskSystem implements TypeSystem<TypeMask> {
|
|||
TypeMask intersection = leftType.intersection(rightType, classWorld);
|
||||
return intersection.isEmpty && !intersection.isNullable;
|
||||
}
|
||||
|
||||
AbstractBool isSubtypeOf(TypeMask value,
|
||||
types.DartType type,
|
||||
{bool allowNull}) {
|
||||
assert(allowNull != null);
|
||||
if (type is types.DynamicType) {
|
||||
if (!allowNull && value.isNullable) return AbstractBool.Maybe;
|
||||
return AbstractBool.True;
|
||||
}
|
||||
if (type is types.InterfaceType) {
|
||||
TypeMask typeAsMask = allowNull
|
||||
? new TypeMask.subtype(type.element, classWorld)
|
||||
: new TypeMask.nonNullSubtype(type.element, classWorld);
|
||||
if (areDisjoint(value, typeAsMask)) {
|
||||
// Disprove the subtype relation based on the class alone.
|
||||
return AbstractBool.False;
|
||||
}
|
||||
if (!type.treatAsRaw) {
|
||||
// If there are type arguments, we cannot prove the subtype relation,
|
||||
// because the type arguments are unknown on both the value and type.
|
||||
return AbstractBool.Maybe;
|
||||
}
|
||||
if (typeAsMask.containsMask(value, classWorld)) {
|
||||
// All possible values are contained in the set of allowed values.
|
||||
// Note that we exploit the fact that [typeAsMask] is an exact
|
||||
// representation of [type], not an approximation.
|
||||
return AbstractBool.True;
|
||||
}
|
||||
// The value is neither contained in the type, nor disjoint from the type.
|
||||
return AbstractBool.Maybe;
|
||||
}
|
||||
// TODO(asgerf): Support function types, and what else might be missing.
|
||||
return AbstractBool.Maybe;
|
||||
}
|
||||
}
|
||||
|
||||
class ConstantPropagationLattice<T> {
|
||||
final TypeSystem<T> typeSystem;
|
||||
final ConstantSystem constantSystem;
|
||||
final types.DartTypes dartTypes;
|
||||
|
||||
ConstantPropagationLattice(this.typeSystem,
|
||||
this.constantSystem,
|
||||
this.dartTypes);
|
||||
|
||||
final _AbstractValue<T> nothing = new _AbstractValue<T>.nothing();
|
||||
|
||||
_AbstractValue<T> constant(ConstantValue value) {
|
||||
return new _AbstractValue<T>.constantValue(value,
|
||||
typeSystem.getTypeOf(value));
|
||||
}
|
||||
|
||||
_AbstractValue<T> nonConstant(T type) {
|
||||
return new _AbstractValue<T>.nonConstant(type);
|
||||
}
|
||||
|
||||
_AbstractValue<T> get anything {
|
||||
return new _AbstractValue<T>.nonConstant(typeSystem.dynamicType);
|
||||
}
|
||||
|
||||
/// Returns whether the given [value] is an instance of [type].
|
||||
///
|
||||
/// Since [value] and [type] are not always known, [AbstractBool.Maybe] is
|
||||
/// returned if the answer is not known.
|
||||
///
|
||||
/// [AbstractBool.Nothing] is returned if [value] is nothing.
|
||||
///
|
||||
/// If [allowNull] is true, `null` is considered to an instance of anything,
|
||||
/// otherwise it is only considered an instance of [Object], [dynamic], and
|
||||
/// [Null].
|
||||
AbstractBool isSubtypeOf(_AbstractValue<T> value,
|
||||
types.DartType type,
|
||||
{bool allowNull}) {
|
||||
assert(allowNull != null);
|
||||
if (value.isNothing) {
|
||||
return AbstractBool.Nothing;
|
||||
}
|
||||
if (value.isConstant) {
|
||||
if (value.constant.isNull) {
|
||||
if (allowNull ||
|
||||
type.isObject ||
|
||||
type.isDynamic ||
|
||||
type == dartTypes.coreTypes.nullType) {
|
||||
return AbstractBool.True;
|
||||
}
|
||||
if (type is types.TypeVariableType) {
|
||||
return AbstractBool.Maybe;
|
||||
}
|
||||
return AbstractBool.False;
|
||||
}
|
||||
types.DartType valueType = value.constant.getType(dartTypes.coreTypes);
|
||||
if (constantSystem.isSubtype(dartTypes, valueType, type)) {
|
||||
return AbstractBool.True;
|
||||
}
|
||||
if (!dartTypes.isPotentialSubtype(valueType, type)) {
|
||||
return AbstractBool.False;
|
||||
}
|
||||
return AbstractBool.Maybe;
|
||||
}
|
||||
return typeSystem.isSubtypeOf(value.type, type, allowNull: allowNull);
|
||||
}
|
||||
|
||||
/// Returns the possible results of applying [operator] to [value],
|
||||
/// assuming the operation does not throw.
|
||||
///
|
||||
/// Because we do not explicitly track thrown values, we currently use the
|
||||
/// convention that constant values are returned from this method only
|
||||
/// if the operation is known not to throw.
|
||||
_AbstractValue<T> unaryOp(UnaryOperator operator,
|
||||
_AbstractValue<T> value) {
|
||||
// TODO(asgerf): Also return information about whether this can throw?
|
||||
if (value.isNothing) {
|
||||
return nothing;
|
||||
}
|
||||
if (value.isConstant) {
|
||||
UnaryOperation operation = constantSystem.lookupUnary(operator);
|
||||
ConstantValue result = operation.fold(value.constant);
|
||||
if (result == null) return anything;
|
||||
return constant(result);
|
||||
}
|
||||
return anything; // TODO(asgerf): Look up type.
|
||||
}
|
||||
|
||||
/// Returns the possible results of applying [operator] to [left], [right],
|
||||
/// assuming the operation does not throw.
|
||||
///
|
||||
/// Because we do not explicitly track thrown values, we currently use the
|
||||
/// convention that constant values are returned from this method only
|
||||
/// if the operation is known not to throw.
|
||||
_AbstractValue<T> binaryOp(BinaryOperator operator,
|
||||
_AbstractValue<T> left,
|
||||
_AbstractValue<T> right) {
|
||||
if (left.isNothing || right.isNothing) {
|
||||
return nothing;
|
||||
}
|
||||
if (left.isConstant && right.isConstant) {
|
||||
BinaryOperation operation = constantSystem.lookupBinary(operator);
|
||||
ConstantValue result = operation.fold(left.constant, right.constant);
|
||||
if (result == null) return anything;
|
||||
return constant(result);
|
||||
}
|
||||
return anything; // TODO(asgerf): Look up type.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -162,35 +318,41 @@ class TypePropagator<T> extends Pass {
|
|||
final ConstantSystem _constantSystem;
|
||||
final TypeSystem _typeSystem;
|
||||
final dart2js.InternalErrorFunction _internalError;
|
||||
final Map<Node, _AbstractValue> _types;
|
||||
final Map<Primitive, _AbstractValue> _types = <Primitive, _AbstractValue>{};
|
||||
|
||||
TypePropagator(this._dartTypes,
|
||||
this._constantSystem,
|
||||
this._typeSystem,
|
||||
this._internalError)
|
||||
: _types = <Node, _AbstractValue>{};
|
||||
this._internalError);
|
||||
|
||||
@override
|
||||
void rewrite(FunctionDefinition root) {
|
||||
// Set all parent pointers.
|
||||
new ParentVisitor().visit(root);
|
||||
|
||||
ConstantPropagationLattice<T> lattice = new ConstantPropagationLattice<T>(
|
||||
_typeSystem, _constantSystem, _dartTypes);
|
||||
Map<Expression, ConstantValue> replacements = <Expression, ConstantValue>{};
|
||||
|
||||
// Analyze. In this phase, the entire term is analyzed for reachability
|
||||
// and the abstract value of each expression.
|
||||
_TypePropagationVisitor<T> analyzer = new _TypePropagationVisitor<T>(
|
||||
_constantSystem,
|
||||
_typeSystem,
|
||||
lattice,
|
||||
_types,
|
||||
_internalError,
|
||||
_dartTypes);
|
||||
replacements,
|
||||
_internalError);
|
||||
|
||||
analyzer.analyze(root);
|
||||
|
||||
// Transform. Uses the data acquired in the previous analysis phase to
|
||||
// replace branches with fixed targets and side-effect-free expressions
|
||||
// with constant results.
|
||||
// with constant results or existing values that are in scope.
|
||||
_TransformingVisitor<T> transformer = new _TransformingVisitor<T>(
|
||||
analyzer.reachableNodes, analyzer.values, _internalError, _typeSystem);
|
||||
lattice,
|
||||
analyzer.reachableNodes,
|
||||
analyzer.values,
|
||||
replacements,
|
||||
_internalError);
|
||||
transformer.transform(root);
|
||||
}
|
||||
|
||||
|
@ -204,49 +366,52 @@ class TypePropagator<T> extends Pass {
|
|||
class _TransformingVisitor<T> extends RecursiveVisitor {
|
||||
final Set<Node> reachable;
|
||||
final Map<Node, _AbstractValue> values;
|
||||
final TypeSystem<T> typeSystem;
|
||||
final Map<Expression, ConstantValue> replacements;
|
||||
final ConstantPropagationLattice<T> valueLattice;
|
||||
|
||||
TypeSystem<T> get typeSystem => valueLattice.typeSystem;
|
||||
|
||||
final dart2js.InternalErrorFunction internalError;
|
||||
|
||||
_TransformingVisitor(this.reachable,
|
||||
_TransformingVisitor(this.valueLattice,
|
||||
this.reachable,
|
||||
this.values,
|
||||
this.internalError,
|
||||
this.typeSystem);
|
||||
this.replacements,
|
||||
this.internalError);
|
||||
|
||||
void transform(FunctionDefinition root) {
|
||||
visit(root);
|
||||
}
|
||||
|
||||
Constant makeConstantPrimitive(ConstantValue constant) {
|
||||
ConstantExpression constExp =
|
||||
const ConstantExpressionCreator().convert(constant);
|
||||
Constant primitive = new Constant(constExp, constant);
|
||||
values[primitive] = new _AbstractValue.constantValue(constant,
|
||||
typeSystem.getTypeOf(constant));
|
||||
return primitive;
|
||||
}
|
||||
|
||||
/// Given an expression with a known constant result and a continuation,
|
||||
/// replaces the expression by a new LetPrim / InvokeContinuation construct.
|
||||
/// `unlink` is a closure responsible for unlinking all removed references.
|
||||
LetPrim constifyExpression(Expression node,
|
||||
Continuation continuation,
|
||||
void unlink()) {
|
||||
_AbstractValue value = values[node];
|
||||
if (value == null || !value.isConstant) {
|
||||
return null;
|
||||
}
|
||||
ConstantValue constant = replacements[node];
|
||||
if (constant == null) return null;
|
||||
|
||||
assert(continuation.parameters.length == 1);
|
||||
|
||||
// Set up the replacement structure.
|
||||
PrimitiveConstantValue primitiveConstant = value.constant;
|
||||
ConstantExpression constExp =
|
||||
const ConstantExpressionCreator().convert(primitiveConstant);
|
||||
Constant constant = new Constant(constExp, primitiveConstant);
|
||||
LetPrim letPrim = new LetPrim(constant);
|
||||
InvokeContinuation invoke =
|
||||
new InvokeContinuation(continuation, <Primitive>[constant]);
|
||||
|
||||
invoke.parent = constant.parent = letPrim;
|
||||
letPrim.body = invoke;
|
||||
|
||||
// Replace the method invocation.
|
||||
|
||||
InteriorNode parent = node.parent;
|
||||
letPrim.parent = parent;
|
||||
Constant primitive = makeConstantPrimitive(constant);
|
||||
LetPrim letPrim = new LetPrim(primitive);
|
||||
|
||||
InvokeContinuation invoke =
|
||||
new InvokeContinuation(continuation, <Primitive>[primitive]);
|
||||
parent.body = letPrim;
|
||||
letPrim.body = invoke;
|
||||
invoke.parent = letPrim;
|
||||
letPrim.parent = parent;
|
||||
|
||||
unlink();
|
||||
|
||||
|
@ -334,20 +499,34 @@ class _TransformingVisitor<T> extends RecursiveVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
// See [visitInvokeMethod].
|
||||
void visitTypeOperator(TypeOperator node) {
|
||||
void visitTypeCast(TypeCast node) {
|
||||
Continuation cont = node.continuation.definition;
|
||||
LetPrim letPrim = constifyExpression(node, cont, () {
|
||||
node.value.unlink();
|
||||
node.typeArguments.forEach((Reference ref) => ref.unlink());
|
||||
node.continuation.unlink();
|
||||
});
|
||||
InteriorNode parent = node.parent;
|
||||
|
||||
if (letPrim == null) {
|
||||
super.visitTypeOperator(node);
|
||||
} else {
|
||||
visitLetPrim(letPrim);
|
||||
_AbstractValue<T> value = getValue(node.value.definition);
|
||||
switch (valueLattice.isSubtypeOf(value, node.type, allowNull: true)) {
|
||||
case AbstractBool.Maybe:
|
||||
case AbstractBool.Nothing:
|
||||
break;
|
||||
|
||||
case AbstractBool.True:
|
||||
// Cast always succeeds, replace it with InvokeContinuation.
|
||||
InvokeContinuation invoke =
|
||||
new InvokeContinuation.fromCall(node.continuation, node.value);
|
||||
parent.body = invoke;
|
||||
invoke.parent = parent;
|
||||
super.visitInvokeContinuation(invoke);
|
||||
return;
|
||||
|
||||
case AbstractBool.False:
|
||||
// Cast always fails, remove unreachable continuation body.
|
||||
assert(!reachable.contains(cont));
|
||||
RemovalVisitor.remove(cont.body);
|
||||
cont.body = new Unreachable()..parent = cont;
|
||||
break;
|
||||
}
|
||||
|
||||
super.visitTypeCast(node);
|
||||
}
|
||||
|
||||
_AbstractValue<T> getValue(Primitive primitive) {
|
||||
|
@ -367,6 +546,24 @@ class _TransformingVisitor<T> extends RecursiveVisitor {
|
|||
left.substituteFor(node);
|
||||
}
|
||||
}
|
||||
|
||||
void visitLetPrim(LetPrim node) {
|
||||
_AbstractValue<T> value = getValue(node.primitive);
|
||||
if (node.primitive is! Constant && value.isConstant) {
|
||||
// If the value is a known constant, compile it as a constant.
|
||||
Constant newPrim = makeConstantPrimitive(value.constant);
|
||||
LetPrim newLet = new LetPrim(newPrim);
|
||||
node.parent.body = newLet;
|
||||
newLet.body = node.body;
|
||||
node.body.parent = newLet;
|
||||
newLet.parent = node.parent;
|
||||
newPrim.substituteFor(node.primitive);
|
||||
RemovalVisitor.remove(node.primitive);
|
||||
visit(newLet.body);
|
||||
} else {
|
||||
super.visitLetPrim(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -391,10 +588,10 @@ class _TypePropagationVisitor<T> implements Visitor {
|
|||
// since their lattice value has changed.
|
||||
final Set<Definition> defWorkset = new Set<Definition>();
|
||||
|
||||
final ConstantSystem constantSystem;
|
||||
final TypeSystem<T> typeSystem;
|
||||
final ConstantPropagationLattice<T> valueLattice;
|
||||
final dart2js.InternalErrorFunction internalError;
|
||||
final types.DartTypes _dartTypes;
|
||||
|
||||
TypeSystem get typeSystem => valueLattice.typeSystem;
|
||||
|
||||
_AbstractValue<T> nothing = new _AbstractValue.nothing();
|
||||
|
||||
|
@ -412,14 +609,16 @@ class _TypePropagationVisitor<T> implements Visitor {
|
|||
// Stores the current lattice value for nodes. Note that it contains not only
|
||||
// definitions as keys, but also expressions such as method invokes.
|
||||
// Access through [getValue] and [setValue].
|
||||
final Map<Node, _AbstractValue<T>> values;
|
||||
final Map<Primitive, _AbstractValue<T>> values;
|
||||
|
||||
_TypePropagationVisitor(this.constantSystem,
|
||||
TypeSystem typeSystem,
|
||||
/// Expressions that invoke their call continuation with a constant value
|
||||
/// and without any side effects. These can be replaced by the constant.
|
||||
final Map<Expression, ConstantValue> replacements;
|
||||
|
||||
_TypePropagationVisitor(this.valueLattice,
|
||||
this.values,
|
||||
this.internalError,
|
||||
this._dartTypes)
|
||||
: this.typeSystem = typeSystem;
|
||||
this.replacements,
|
||||
this.internalError);
|
||||
|
||||
void analyze(FunctionDefinition root) {
|
||||
reachableNodes.clear();
|
||||
|
@ -560,63 +759,54 @@ class _TypePropagationVisitor<T> implements Visitor {
|
|||
Continuation cont = node.continuation.definition;
|
||||
setReachable(cont);
|
||||
|
||||
/// Sets the value of both the current node and the target continuation
|
||||
/// parameter.
|
||||
void setValues(_AbstractValue<T> updateValue) {
|
||||
setValue(node, updateValue);
|
||||
/// Sets the value of the target continuation parameter, and possibly
|
||||
/// try to replace the whole invocation with a constant.
|
||||
void setResult(_AbstractValue<T> updateValue, {bool canReplace: false}) {
|
||||
Parameter returnValue = cont.parameters[0];
|
||||
setValue(returnValue, updateValue);
|
||||
if (canReplace && updateValue.isConstant) {
|
||||
replacements[node] = updateValue.constant;
|
||||
} else {
|
||||
// A previous iteration might have tried to replace this.
|
||||
replacements.remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
_AbstractValue<T> lhs = getValue(node.receiver.definition);
|
||||
if (lhs.isNothing) {
|
||||
return; // And come back later.
|
||||
} else if (lhs.isNonConst) {
|
||||
setValues(nonConstant(typeSystem.getSelectorReturnType(node.selector)));
|
||||
return;
|
||||
} else if (!node.selector.isOperator) {
|
||||
}
|
||||
if (!node.selector.isOperator) {
|
||||
// TODO(jgruber): Handle known methods on constants such as String.length.
|
||||
setValues(nonConstant());
|
||||
setResult(nonConstant(typeSystem.getSelectorReturnType(node.selector)));
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(asgerf): Support constant folding on intercepted calls!
|
||||
|
||||
// Calculate the resulting constant if possible.
|
||||
ConstantValue result;
|
||||
_AbstractValue<T> result;
|
||||
String opname = node.selector.name;
|
||||
if (node.selector.argumentCount == 0) {
|
||||
// Unary operator.
|
||||
|
||||
if (opname == "unary-") {
|
||||
opname = "-";
|
||||
}
|
||||
UnaryOperation operation = constantSystem.lookupUnary(
|
||||
UnaryOperator.parse(opname));
|
||||
if (operation != null) {
|
||||
result = operation.fold(lhs.constant);
|
||||
}
|
||||
UnaryOperator operator = UnaryOperator.parse(opname);
|
||||
result = valueLattice.unaryOp(operator, lhs);
|
||||
} else if (node.selector.argumentCount == 1) {
|
||||
// Binary operator.
|
||||
|
||||
_AbstractValue<T> rhs = getValue(node.arguments[0].definition);
|
||||
if (!rhs.isConstant) {
|
||||
setValues(nonConstant());
|
||||
return;
|
||||
}
|
||||
|
||||
BinaryOperation operation = constantSystem.lookupBinary(
|
||||
BinaryOperator.parse(opname));
|
||||
if (operation != null) {
|
||||
result = operation.fold(lhs.constant, rhs.constant);
|
||||
}
|
||||
BinaryOperator operator = BinaryOperator.parse(opname);
|
||||
result = valueLattice.binaryOp(operator, lhs, rhs);
|
||||
}
|
||||
|
||||
// Update value of the continuation parameter. Again, this is effectively
|
||||
// a phi.
|
||||
if (result == null) {
|
||||
setValues(nonConstant());
|
||||
setResult(nonConstant());
|
||||
} else {
|
||||
T type = typeSystem.getTypeOf(result);
|
||||
setValues(constantValue(result, type));
|
||||
setResult(result, canReplace: true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -643,10 +833,17 @@ class _TypePropagationVisitor<T> implements Visitor {
|
|||
Continuation cont = node.continuation.definition;
|
||||
setReachable(cont);
|
||||
|
||||
void setValues(_AbstractValue<T> updateValue) {
|
||||
setValue(node, updateValue);
|
||||
/// Sets the value of the target continuation parameter, and possibly
|
||||
/// try to replace the whole invocation with a constant.
|
||||
void setResult(_AbstractValue<T> updateValue, {bool canReplace: false}) {
|
||||
Parameter returnValue = cont.parameters[0];
|
||||
setValue(returnValue, updateValue);
|
||||
if (canReplace && updateValue.isConstant) {
|
||||
replacements[node] = updateValue.constant;
|
||||
} else {
|
||||
// A previous iteration might have tried to replace this.
|
||||
replacements.remove(node);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jgruber): Currently we only optimize if all arguments are string
|
||||
|
@ -670,9 +867,9 @@ class _TypePropagationVisitor<T> implements Visitor {
|
|||
});
|
||||
LiteralDartString dartString = new LiteralDartString(allStrings.join());
|
||||
ConstantValue constant = new StringConstantValue(dartString);
|
||||
setValues(constantValue(constant, type));
|
||||
setResult(constantValue(constant, type), canReplace: true);
|
||||
} else {
|
||||
setValues(nonConstant(type));
|
||||
setResult(nonConstant(type));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -682,6 +879,9 @@ class _TypePropagationVisitor<T> implements Visitor {
|
|||
void visitRethrow(Rethrow node) {
|
||||
}
|
||||
|
||||
void visitUnreachable(Unreachable node) {
|
||||
}
|
||||
|
||||
void visitNonTailThrow(NonTailThrow node) {
|
||||
internalError(null, 'found non-tail throw after they were eliminated');
|
||||
}
|
||||
|
@ -709,50 +909,47 @@ class _TypePropagationVisitor<T> implements Visitor {
|
|||
}
|
||||
}
|
||||
|
||||
void visitTypeOperator(TypeOperator node) {
|
||||
void visitTypeTest(TypeTest node) {
|
||||
_AbstractValue<T> input = getValue(node.value.definition);
|
||||
T boolType = typeSystem.boolType;
|
||||
switch(valueLattice.isSubtypeOf(input, node.type, allowNull: false)) {
|
||||
case AbstractBool.Nothing:
|
||||
break; // And come back later.
|
||||
|
||||
case AbstractBool.True:
|
||||
setValue(node, constantValue(new TrueConstantValue(), boolType));
|
||||
break;
|
||||
|
||||
case AbstractBool.False:
|
||||
setValue(node, constantValue(new FalseConstantValue(), boolType));
|
||||
break;
|
||||
|
||||
case AbstractBool.Maybe:
|
||||
setValue(node, nonConstant(boolType));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void visitTypeCast(TypeCast node) {
|
||||
Continuation cont = node.continuation.definition;
|
||||
setReachable(cont);
|
||||
_AbstractValue<T> input = getValue(node.value.definition);
|
||||
switch (valueLattice.isSubtypeOf(input, node.type, allowNull: true)) {
|
||||
case AbstractBool.Nothing:
|
||||
break; // And come back later.
|
||||
|
||||
void setValues(_AbstractValue<T> updateValue) {
|
||||
setValue(node, updateValue);
|
||||
Parameter returnValue = cont.parameters[0];
|
||||
setValue(returnValue, updateValue);
|
||||
}
|
||||
case AbstractBool.True:
|
||||
setReachable(cont);
|
||||
setValue(cont.parameters.single, input);
|
||||
break;
|
||||
|
||||
if (node.isTypeCast) {
|
||||
// TODO(jgruber): Add support for `as` casts.
|
||||
setValues(nonConstant());
|
||||
return;
|
||||
}
|
||||
case AbstractBool.False:
|
||||
break; // Cast fails. Continuation should remain unreachable.
|
||||
|
||||
_AbstractValue<T> cell = getValue(node.value.definition);
|
||||
if (cell.isNothing) {
|
||||
return; // And come back later.
|
||||
} else if (cell.isConstant && node.type.kind == types.TypeKind.INTERFACE) {
|
||||
// Receiver is a constant, perform is-checks at compile-time.
|
||||
|
||||
types.InterfaceType checkedType = node.type;
|
||||
ConstantValue constant = cell.constant;
|
||||
types.DartType constantType = constant.getType(_dartTypes.coreTypes);
|
||||
|
||||
T type = typeSystem.boolType;
|
||||
_AbstractValue<T> result;
|
||||
if (constant.isNull &&
|
||||
checkedType != _dartTypes.coreTypes.nullType &&
|
||||
checkedType != _dartTypes.coreTypes.objectType) {
|
||||
// `(null is Type)` is true iff Type is in { Null, Object }.
|
||||
result = constantValue(new FalseConstantValue(), type);
|
||||
} else {
|
||||
// Otherwise, perform a standard subtype check.
|
||||
result = constantValue(
|
||||
constantSystem.isSubtype(_dartTypes, constantType, checkedType)
|
||||
? new TrueConstantValue()
|
||||
: new FalseConstantValue(),
|
||||
type);
|
||||
}
|
||||
setValues(result);
|
||||
} else {
|
||||
setValues(nonConstant(typeSystem.boolType));
|
||||
case AbstractBool.Maybe:
|
||||
// TODO(asgerf): Narrow type of output to those that survive the cast.
|
||||
setReachable(cont);
|
||||
setValue(cont.parameters.single, input);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1232,6 +1232,10 @@ abstract class DartTypes {
|
|||
|
||||
/// Returns `true` if [t] is a subtype of [s].
|
||||
bool isSubtype(DartType t, DartType s);
|
||||
|
||||
/// Returns `true` if [t] might be a subtype of [s] for some values of
|
||||
/// type variables in [s] and [t].
|
||||
bool isPotentialSubtype(DartType t, DartType s);
|
||||
}
|
||||
|
||||
class Types implements DartTypes {
|
||||
|
|
|
@ -1766,18 +1766,26 @@ class JavaScriptBackend extends Backend {
|
|||
return findHelper('assertSubtype');
|
||||
}
|
||||
|
||||
Element getSubtypeCast() {
|
||||
return findHelper('subtypeCast');
|
||||
}
|
||||
|
||||
Element getCheckSubtypeOfRuntimeType() {
|
||||
return findHelper('checkSubtypeOfRuntimeType');
|
||||
}
|
||||
|
||||
Element getCheckDeferredIsLoaded() {
|
||||
return findHelper('checkDeferredIsLoaded');
|
||||
}
|
||||
|
||||
Element getAssertSubtypeOfRuntimeType() {
|
||||
return findHelper('assertSubtypeOfRuntimeType');
|
||||
}
|
||||
|
||||
Element getSubtypeOfRuntimeTypeCast() {
|
||||
return findHelper('subtypeOfRuntimeTypeCast');
|
||||
}
|
||||
|
||||
Element getCheckDeferredIsLoaded() {
|
||||
return findHelper('checkDeferredIsLoaded');
|
||||
}
|
||||
|
||||
Element getThrowNoSuchMethod() {
|
||||
return findHelper('throwNoSuchMethod');
|
||||
}
|
||||
|
|
|
@ -355,23 +355,21 @@ class CodeGenerator extends tree_ir.StatementVisitor
|
|||
js.Expression visitTypeOperator(tree_ir.TypeOperator node) {
|
||||
js.Expression value = visitExpression(node.value);
|
||||
List<js.Expression> typeArguments = visitExpressionList(node.typeArguments);
|
||||
if (!node.isTypeTest) {
|
||||
giveup(node, 'type casts not implemented.');
|
||||
}
|
||||
DartType type = node.type;
|
||||
// Note that the trivial (but special) cases of Object, dynamic, and Null
|
||||
// are handled at build-time and must not occur in a TypeOperator.
|
||||
assert(!type.isObject && !type.isDynamic);
|
||||
if (type is InterfaceType) {
|
||||
glue.registerIsCheck(type, registry);
|
||||
ClassElement clazz = type.element;
|
||||
|
||||
// We use the helper:
|
||||
// We use one of the two helpers:
|
||||
//
|
||||
// checkSubtype(value, $isT, typeArgs, $asT)
|
||||
// subtypeCast(value, $isT, typeArgs, $asT)
|
||||
//
|
||||
// Any of the last two arguments may be null if there are no type
|
||||
// arguments, and/or if no substitution is required.
|
||||
Element function = node.isTypeTest
|
||||
? glue.getCheckSubtype()
|
||||
: glue.getSubtypeCast();
|
||||
|
||||
js.Expression isT = js.string(glue.getTypeTestTag(type));
|
||||
|
||||
|
@ -384,14 +382,20 @@ class CodeGenerator extends tree_ir.StatementVisitor
|
|||
: new js.LiteralNull();
|
||||
|
||||
return buildStaticHelperInvocation(
|
||||
glue.getCheckSubtype(),
|
||||
function,
|
||||
<js.Expression>[value, isT, typeArgumentArray, asT]);
|
||||
} else if (type is TypeVariableType) {
|
||||
glue.registerIsCheck(type, registry);
|
||||
|
||||
Element function = node.isTypeTest
|
||||
? glue.getCheckSubtypeOfRuntimeType()
|
||||
: glue.getSubtypeOfRuntimeTypeCast();
|
||||
|
||||
// The only type argument is the type held in the type variable.
|
||||
js.Expression typeValue = typeArguments.single;
|
||||
|
||||
return buildStaticHelperInvocation(
|
||||
glue.getCheckSubtypeOfRuntime(),
|
||||
function,
|
||||
<js.Expression>[value, typeValue]);
|
||||
}
|
||||
return giveup(node, 'type check unimplemented for $type.');
|
||||
|
@ -546,6 +550,12 @@ class CodeGenerator extends tree_ir.StatementVisitor
|
|||
glue.reportInternalError('rethrow seen in JavaScript output');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitUnreachable(tree_ir.Unreachable node) {
|
||||
// Output nothing.
|
||||
// TODO(asgerf): Emit a throw/return to assist local analysis in the VM?
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTry(tree_ir.Try node) {
|
||||
js.Block tryBlock = buildBodyBlock(node.tryBody);
|
||||
|
|
|
@ -176,11 +176,21 @@ class Glue {
|
|||
return _backend.getCheckSubtype();
|
||||
}
|
||||
|
||||
/// subtypeCast(value, $isT, typeArgs, $asT)
|
||||
FunctionElement getSubtypeCast() {
|
||||
return _backend.getSubtypeCast();
|
||||
}
|
||||
|
||||
/// checkSubtypeOfRuntime(value, runtimeType)
|
||||
FunctionElement getCheckSubtypeOfRuntime() {
|
||||
FunctionElement getCheckSubtypeOfRuntimeType() {
|
||||
return _backend.getCheckSubtypeOfRuntimeType();
|
||||
}
|
||||
|
||||
/// subtypeOfRuntimeTypeCast(value, runtimeType)
|
||||
FunctionElement getSubtypeOfRuntimeTypeCast() {
|
||||
return _backend.getSubtypeOfRuntimeTypeCast();
|
||||
}
|
||||
|
||||
js.Expression getRuntimeTypeName(ClassElement cls) {
|
||||
return js.string(_namer.runtimeTypeName(cls));
|
||||
}
|
||||
|
|
|
@ -435,6 +435,10 @@ class StatementRewriter extends Transformer implements Pass {
|
|||
return node;
|
||||
}
|
||||
|
||||
Statement visitUnreachable(Unreachable node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
Statement visitBreak(Break node) {
|
||||
// Redirect through chain of breaks.
|
||||
// Note that useCount was accounted for at visitLabeledStatement.
|
||||
|
|
|
@ -380,6 +380,10 @@ class Builder implements cps_ir.Visitor<Node> {
|
|||
return new Rethrow();
|
||||
}
|
||||
|
||||
Statement visitUnreachable(cps_ir.Unreachable node) {
|
||||
return new Unreachable();
|
||||
}
|
||||
|
||||
Expression visitNonTailThrow(cps_ir.NonTailThrow node) {
|
||||
unexpectedNode(node);
|
||||
}
|
||||
|
@ -415,13 +419,18 @@ class Builder implements cps_ir.Visitor<Node> {
|
|||
return Assign.makeStatement(variable, value, visit(node.body));
|
||||
}
|
||||
|
||||
Statement visitTypeOperator(cps_ir.TypeOperator node) {
|
||||
Statement visitTypeCast(cps_ir.TypeCast node) {
|
||||
Expression value = getVariableUse(node.value);
|
||||
List<Expression> typeArgs = translateArguments(node.typeArguments);
|
||||
Expression concat =
|
||||
new TypeOperator(value, node.type, typeArgs,
|
||||
isTypeTest: node.isTypeTest);
|
||||
return continueWithExpression(node.continuation, concat);
|
||||
Expression expression =
|
||||
new TypeOperator(value, node.type, typeArgs, isTypeTest: false);
|
||||
return continueWithExpression(node.continuation, expression);
|
||||
}
|
||||
|
||||
Expression visitTypeTest(cps_ir.TypeTest node) {
|
||||
Expression value = getVariableUse(node.value);
|
||||
List<Expression> typeArgs = translateArguments(node.typeArguments);
|
||||
return new TypeOperator(value, node.type, typeArgs, isTypeTest: true);
|
||||
}
|
||||
|
||||
Statement visitInvokeConstructor(cps_ir.InvokeConstructor node) {
|
||||
|
|
|
@ -78,8 +78,7 @@ class Label {
|
|||
/**
|
||||
* A local variable in the tree IR.
|
||||
*
|
||||
* All tree IR variables are mutable, and may in Dart-mode be referenced inside
|
||||
* nested functions.
|
||||
* All tree IR variables are mutable.
|
||||
*
|
||||
* To use a variable as an expression, reference it from a [VariableUse], with
|
||||
* one [VariableUse] per expression.
|
||||
|
@ -324,6 +323,10 @@ class LiteralMap extends Expression {
|
|||
}
|
||||
}
|
||||
|
||||
/// Type test or type cast.
|
||||
///
|
||||
/// Note that if this is a type test, then [type] cannot be `Object`, `dynamic`,
|
||||
/// or the `Null` type. These cases are compiled to other node types.
|
||||
class TypeOperator extends Expression {
|
||||
Expression value;
|
||||
final DartType type;
|
||||
|
@ -618,6 +621,17 @@ class Try extends Statement {
|
|||
}
|
||||
}
|
||||
|
||||
/// A statement that is known to be unreachable.
|
||||
class Unreachable extends Statement {
|
||||
Statement get next => null;
|
||||
void set next(Statement value) => throw 'UNREACHABLE';
|
||||
|
||||
accept(StatementVisitor visitor) => visitor.visitUnreachable(this);
|
||||
accept1(StatementVisitor1 visitor, arg) {
|
||||
return visitor.visitUnreachable(this, arg);
|
||||
}
|
||||
}
|
||||
|
||||
class FunctionDefinition extends Node {
|
||||
final ExecutableElement element;
|
||||
final List<Variable> parameters;
|
||||
|
@ -828,6 +842,7 @@ abstract class StatementVisitor<S> {
|
|||
S visitWhileCondition(WhileCondition node);
|
||||
S visitExpressionStatement(ExpressionStatement node);
|
||||
S visitTry(Try node);
|
||||
S visitUnreachable(Unreachable node);
|
||||
}
|
||||
|
||||
abstract class StatementVisitor1<S, A> {
|
||||
|
@ -843,6 +858,7 @@ abstract class StatementVisitor1<S, A> {
|
|||
S visitWhileCondition(WhileCondition node, A arg);
|
||||
S visitExpressionStatement(ExpressionStatement node, A arg);
|
||||
S visitTry(Try node, A arg);
|
||||
S visitUnreachable(Unreachable node, A arg);
|
||||
}
|
||||
|
||||
abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
|
||||
|
@ -1007,6 +1023,8 @@ abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
|
|||
visitCreateInvocationMirror(CreateInvocationMirror node) {
|
||||
node.arguments.forEach(visitExpression);
|
||||
}
|
||||
|
||||
visitUnreachable(Unreachable node) {}
|
||||
}
|
||||
|
||||
abstract class Transformer implements ExpressionVisitor<Expression>,
|
||||
|
@ -1203,4 +1221,8 @@ class RecursiveTransformer extends Transformer {
|
|||
_replaceExpressions(node.arguments);
|
||||
return node;
|
||||
}
|
||||
|
||||
visitUnreachable(Unreachable node) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,6 +86,10 @@ class BlockCollector extends StatementVisitor {
|
|||
_addStatement(node);
|
||||
}
|
||||
|
||||
visitUnreachable(Unreachable node) {
|
||||
_addStatement(node);
|
||||
}
|
||||
|
||||
visitBreak(Break node) {
|
||||
_addStatement(node);
|
||||
blocks.last.addEdgeTo(breakTargets[node.target]);
|
||||
|
@ -261,6 +265,10 @@ class TreeTracer extends TracerUtil with StatementVisitor {
|
|||
printStatement(null, "rethrow");
|
||||
}
|
||||
|
||||
visitUnreachable(Unreachable node) {
|
||||
printStatement(null, "unreachable");
|
||||
}
|
||||
|
||||
visitBreak(Break node) {
|
||||
printStatement(null, "break ${collector.breakTargets[node.target].name}");
|
||||
}
|
||||
|
|
|
@ -9614,7 +9614,6 @@ WebPlatformTest/webstorage/storage_local_setitem_t01: RuntimeError # Please tria
|
|||
WebPlatformTest/webstorage/storage_session_setitem_t01: RuntimeError # Please triage this failure
|
||||
|
||||
[ $compiler == dart2js && $cps_ir ]
|
||||
Language/03_Overview/1_Scoping_A01_t39: Crash # Instance of 'TypeOperator': type check unimplemented for f.
|
||||
Language/03_Overview/1_Scoping_A02_t19: Crash # (switch (1){case 1:var x;break;case 2:var x;break;}): Unhandled node
|
||||
Language/07_Classes/07_Classes_A02_t17: Crash # Please triage this failure.
|
||||
Language/07_Classes/07_Classes_A02_t18: Crash # Please triage this failure.
|
||||
|
@ -9641,18 +9640,8 @@ Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A01_t01: Runtime
|
|||
Language/12_Expressions/22_Equality_A03_t01: RuntimeError # Please triage this failure.
|
||||
Language/12_Expressions/30_Identifier_Reference_A09_t03: Crash # (i=0): For-loop variable captured in loop header
|
||||
Language/12_Expressions/33_Type_Cast_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A01_t04: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A02_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A02_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A02_t03: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A02_t06: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A02_t07: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A02_t08: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A02_t09: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A04_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/33_Type_Cast_A04_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/Expressions_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/12_Expressions/Expressions_A01_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/13_Statements/06_For_A01_t07: Crash # Please triage this failure.
|
||||
Language/13_Statements/09_Switch_A01_t01: Crash # (switch (1){case 0:case 1:}): Unhandled node
|
||||
Language/13_Statements/09_Switch_A01_t02: Crash # (switch (1){l1:l2:l3:case (1):}): Unhandled node
|
||||
|
@ -9705,26 +9694,12 @@ Language/13_Statements/14_Continue_A03_t05: Crash # Unhandled node
|
|||
Language/13_Statements/14_Continue_A03_t06: Crash # try/finally
|
||||
Language/13_Statements/14_Continue_A03_t07: Crash # try/finally
|
||||
Language/14_Libraries_and_Scripts/13_Libraries_and_Scripts_A05_t02: Crash # Instance of 'TypeOperator': type check unimplemented for _td.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A02_t26: Crash # Instance of 'TypeOperator': type check unimplemented for prefix.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A02_t27: Crash # Instance of 'TypeOperator': type check unimplemented for bar.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A02_t28: Crash # Instance of 'TypeOperator': type check unimplemented for bar.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A03_t04: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A03_t24: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A03_t44: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A03_t45: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A03_t64: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/14_Libraries_and_Scripts/1_Imports_A03_t65: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Language/14_Libraries_and_Scripts/2_Exports_A06_t02: Crash # Instance of 'TypeOperator': type check unimplemented for foo.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A01_t03: Crash # Instance of 'TypeOperator': type check unimplemented for f.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A02_t01: Crash # Instance of 'TypeOperator': type check unimplemented for f_t.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A02_t02: Crash # Instance of 'TypeOperator': type check unimplemented for f_t.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A02_t03: Crash # Instance of 'TypeOperator': type check unimplemented for f_t.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A03_t01: Crash # Instance of 'TypeOperator': type check unimplemented for f1.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A04_t01: Crash # Instance of 'TypeOperator': type check unimplemented for f1.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A04_t02: Crash # Instance of 'TypeOperator': type check unimplemented for f1.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A07_t05: Crash # Instance of 'TypeOperator': type check unimplemented for f.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A07_t06: Crash # Instance of 'TypeOperator': type check unimplemented for f.
|
||||
Language/15_Types/3_Type_Declarations/1_Typedef_A07_t07: Crash # Instance of 'TypeOperator': type check unimplemented for f.
|
||||
Language/15_Types/4_Interface_Types_A05_t04: Crash # type expression t1 (typedef)
|
||||
Language/15_Types/4_Interface_Types_A10_t04: Crash # type expression param1 (typedef)
|
||||
Language/15_Types/4_Interface_Types_A10_t06: Crash # type expression f (typedef)
|
||||
|
@ -9775,41 +9750,11 @@ LayoutTests/fast/canvas/webgl/index-validation_t01: Crash # Unhandled node
|
|||
LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/css/css-keyframe-style-crash_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/first-line-parent-style-different_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/media-rule-dyn_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/parsing-css-comment_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/parsing-css-escapes_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/parsing-css-nonascii_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/parsing-css-nth-child_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/parsing-css-surrogate-pairs_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/pseudo-out-of-range_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/pseudo-valid-dynamic_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/css/visited-link-hang_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/dom/location-hash_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/dynamic/inline-to-block-crash_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/encoding/css-charset-dom_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/events/event-attributes-after-exception_t01: Crash # try/finally
|
||||
LayoutTests/fast/files/file-reader-methods-illegal-arguments_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/forms/autofocus-focus-only-once_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/forms/datalist/datalist-child-validation_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/forms/datalist/datalist_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/forms/date/date-interactive-validation-required_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/forms/date/date-pseudo-classes_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/forms/datetimelocal/datetimelocal-pseudo-classes_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/forms/fieldset/fieldset-elements_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/forms/search-popup-crasher_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/loader/hashchange-event-properties_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/media/media-query-list-syntax_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/mediastream/getusermedia_t01: Crash # Please triage this failure.
|
||||
LayoutTests/fast/multicol/hit-test-above-or-below_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/parser/parse-wbr_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/replaced/table-replaced-element_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/selectors/style-sharing-last-child_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/svg/getbbox_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/svg/tabindex-focus_t01: Crash # try/finally
|
||||
LayoutTests/fast/svg/whitespace-angle_t01: Crash # try/finally
|
||||
LayoutTests/fast/svg/whitespace-integer_t01: Crash # try/finally
|
||||
|
@ -9820,47 +9765,9 @@ LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Crash # Unhandled nod
|
|||
LayoutTests/fast/table/hittest-tablecell-right-edge_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: Crash # Unhandled node
|
||||
LayoutTests/fast/table/incorrect-colgroup-span-values_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/table/rowindex-comment-nodes_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/text/font-ligature-letter-spacing_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/anchor_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/file-http-base_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/file_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/host-lowercase-per-scheme_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/host_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/idna2003_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/idna2008_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/invalid-urls-utf8_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/ipv4_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/ipv6_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/mailto_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/path-url_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/path_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/port_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/query_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/relative-unix_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/relative-win_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/relative_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/safari-extension_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/scheme_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/segments-from-data-url_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/segments_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/standard-url_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/trivial-segments_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/url/trivial_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/xpath/name-null-namespace_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/xsl/default-html_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LayoutTests/fast/xsl/extra-lf-at-end_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: RuntimeError # Please triage this failure.
|
||||
LibTest/async/Stream/Stream.periodic_A01_t01: Crash # Please triage this failure.
|
||||
LibTest/async/Stream/drain_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/async/Stream/drain_A02_t01: Crash # Please triage this failure.
|
||||
LibTest/async/Stream/elementAt_A02_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/async/Stream/handleError_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/async/Stream/handleError_A03_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/async/Stream/listen_A03_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/async/Stream/listen_A04_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/async/Stream/take_A01_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/async/Zone/registerBinaryCallback_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for ZoneBinaryCallback.
|
||||
LibTest/async/Zone/registerCallback_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for ZoneCallback.
|
||||
LibTest/async/Zone/registerUnaryCallback_A01_t01: Crash # Instance of 'TypeOperator': type check unimplemented for ZoneUnaryCallback.
|
||||
|
@ -9877,8 +9784,6 @@ LibTest/core/Invocation/memberName_A01_t01: Crash # Please triage this failure.
|
|||
LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # Please triage this failure.
|
||||
LibTest/core/List/List_class_A01_t02: Crash # Please triage this failure.
|
||||
LibTest/core/Map/Map_A01_t01: Crash # type expression SomeFunction (typedef)
|
||||
LibTest/core/Object/operator_equality_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/core/Object/toString_A01_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Crash # Unhandled node
|
||||
LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Crash # Unhandled node
|
||||
LibTest/core/Set/add_A01_t03: RuntimeError # Please triage this failure.
|
||||
|
@ -9900,7 +9805,6 @@ LibTest/html/Window/moveTo_A02_t01: Crash # try/finally
|
|||
LibTest/html/Window/resizeBy_A01_t01: Crash # try/finally
|
||||
LibTest/html/Window/resizeTo_A01_t01: Crash # try/finally
|
||||
LibTest/isolate/ReceivePort/drain_A02_t01: Crash # Please triage this failure.
|
||||
LibTest/isolate/ReceivePort/take_A01_t02: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
Utils/tests/Expect/approxEquals_A04_t01: RuntimeError # Please triage this failure.
|
||||
Utils/tests/Expect/stringEquals_A02_t01: RuntimeError # Please triage this failure.
|
||||
WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: Crash # Unhandled node
|
||||
|
@ -9911,5 +9815,4 @@ WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: Crash # Un
|
|||
WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: Crash # Unhandled node
|
||||
WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: Crash # Unhandled node
|
||||
WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: Crash # Unhandled node
|
||||
WebPlatformTest/html/semantics/forms/the-input-element/datetime_t01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: Crash # Unhandled node
|
||||
|
|
|
@ -135,9 +135,10 @@ class SExpressionUnstringifier {
|
|||
static const String LET_CONT = "LetCont";
|
||||
static const String LET_MUTABLE = "LetMutable";
|
||||
static const String SET_MUTABLE_VARIABLE = "SetMutableVariable";
|
||||
static const String TYPE_OPERATOR = "TypeOperator";
|
||||
static const String TYPE_CAST = "TypeCast";
|
||||
static const String SET_STATIC = "SetStatic";
|
||||
static const String GET_LAZY_STATIC = "GetLazyStatic";
|
||||
static const String UNREACHABLE = "Unreachable";
|
||||
|
||||
// Primitives
|
||||
static const String CONSTANT = "Constant";
|
||||
|
@ -147,6 +148,7 @@ class SExpressionUnstringifier {
|
|||
static const String LITERAL_MAP = "LiteralMap";
|
||||
static const String REIFY_TYPE_VAR = "ReifyTypeVar";
|
||||
static const String GET_STATIC = "GetStatic";
|
||||
static const String TYPE_TEST = "TypeTest";
|
||||
|
||||
// Other
|
||||
static const String FUNCTION_DEFINITION = "FunctionDefinition";
|
||||
|
@ -247,12 +249,14 @@ class SExpressionUnstringifier {
|
|||
return parseLetMutable();
|
||||
case SET_MUTABLE_VARIABLE:
|
||||
return parseSetMutableVariable();
|
||||
case TYPE_OPERATOR:
|
||||
return parseTypeOperator();
|
||||
case TYPE_CAST:
|
||||
return parseTypeCast();
|
||||
case SET_STATIC:
|
||||
return parseSetStatic();
|
||||
case GET_LAZY_STATIC:
|
||||
return parseGetLazyStatic();
|
||||
case UNREACHABLE:
|
||||
return parseUnreachable();
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
@ -553,14 +557,12 @@ class SExpressionUnstringifier {
|
|||
..plug(body);
|
||||
}
|
||||
|
||||
/// (TypeOperator operator recv type cont)
|
||||
TypeOperator parseTypeOperator() {
|
||||
tokens.consumeStart(TYPE_OPERATOR);
|
||||
/// (TypeCast value type args cont)
|
||||
TypeCast parseTypeCast() {
|
||||
tokens.consumeStart(TYPE_CAST);
|
||||
|
||||
String operator = tokens.read();
|
||||
|
||||
Primitive recv = name2variable[tokens.read()];
|
||||
assert(recv != null);
|
||||
Primitive value = name2variable[tokens.read()];
|
||||
assert(value != null);
|
||||
|
||||
dart_types.DartType type = new DummyNamedType(tokens.read());
|
||||
|
||||
|
@ -570,8 +572,22 @@ class SExpressionUnstringifier {
|
|||
assert(cont != null);
|
||||
|
||||
tokens.consumeEnd();
|
||||
return new TypeOperator(recv, type, typeArguments, cont,
|
||||
isTypeTest: operator == 'is');
|
||||
return new TypeCast(value, type, typeArguments, cont);
|
||||
}
|
||||
|
||||
/// (TypeTest value type args)
|
||||
TypeTest parseTypeTest() {
|
||||
tokens.consumeStart(TYPE_TEST);
|
||||
|
||||
Primitive value = name2variable[tokens.read()];
|
||||
assert(value != null);
|
||||
|
||||
dart_types.DartType type = new DummyNamedType(tokens.read());
|
||||
|
||||
List<ir.Primitive> typeArguments = parsePrimitiveList();
|
||||
|
||||
tokens.consumeEnd();
|
||||
return new TypeTest(value, type, typeArguments);
|
||||
}
|
||||
|
||||
/// (SetStatic field value body)
|
||||
|
@ -599,6 +615,13 @@ class SExpressionUnstringifier {
|
|||
return new GetLazyStatic(fieldElement, cont, null);
|
||||
}
|
||||
|
||||
/// (Unreachable)
|
||||
Unreachable parseUnreachable() {
|
||||
tokens.consumeStart(UNREACHABLE);
|
||||
tokens.consumeEnd();
|
||||
return new Unreachable();
|
||||
}
|
||||
|
||||
/// (LetPrim (name primitive) body)
|
||||
LetPrim parseLetPrim() {
|
||||
tokens.consumeStart(LET_PRIM);
|
||||
|
@ -637,6 +660,8 @@ class SExpressionUnstringifier {
|
|||
return parseReifyTypeVar();
|
||||
case GET_STATIC:
|
||||
return parseGetStatic();
|
||||
case TYPE_TEST:
|
||||
return parseTypeTest();
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ main() {
|
|||
r"""
|
||||
function() {
|
||||
var a = null, i = 0;
|
||||
while (J.getInterceptor$n(i).$lt(i, 10)) {
|
||||
while (P.identical(J.getInterceptor$n(i).$lt(i, 10), true)) {
|
||||
a = new V.main_closure(i);
|
||||
i = J.getInterceptor$ns(i).$add(i, 1);
|
||||
}
|
||||
|
|
|
@ -38,10 +38,10 @@ function() {
|
|||
var l = ["hest", ["h", "e", "s", "t"]], i, x, j;
|
||||
P.print(J.getInterceptor$as(l).get$length(l));
|
||||
i = 0;
|
||||
while (J.getInterceptor$n(i).$lt(i, J.getInterceptor$as(l).get$length(l))) {
|
||||
while (P.identical(J.getInterceptor$n(i).$lt(i, J.getInterceptor$as(l).get$length(l)), true)) {
|
||||
x = J.getInterceptor$as(l).$index(l, i);
|
||||
j = 0;
|
||||
while (J.getInterceptor$n(j).$lt(j, J.getInterceptor$as(x).get$length(x))) {
|
||||
while (P.identical(J.getInterceptor$n(j).$lt(j, J.getInterceptor$as(x).get$length(x)), true)) {
|
||||
P.print(J.getInterceptor$as(x).$index(x, j));
|
||||
j = J.getInterceptor$ns(j).$add(j, 1);
|
||||
}
|
||||
|
|
|
@ -62,8 +62,6 @@ deferred_fail_and_retry_test: SkipByDesign # Uses eval to simulate failed loadin
|
|||
deferred_fail_and_retry_worker_test: SkipByDesign # Uses eval to simulate failed loading.
|
||||
|
||||
[ $compiler == dart2js && $cps_ir ]
|
||||
10216a_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
10216b_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
12320_test: Crash # Unhandled node
|
||||
16407_test: Pass # Please triage this failure.
|
||||
17094_test: RuntimeError # Please triage this failure.
|
||||
|
|
|
@ -233,7 +233,7 @@ hash_map2_test: Crash # Instance of 'TypeOperator': type check unimplemented for
|
|||
hash_set_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
hash_set_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
hash_set_type_check_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
hashcode_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
hashcode_test : RuntimeError
|
||||
int_parse_radix_test/01: Crash # Please triage this failure.
|
||||
int_parse_radix_test/02: Crash # Please triage this failure.
|
||||
int_parse_radix_test/none: Crash # Please triage this failure.
|
||||
|
@ -298,7 +298,6 @@ regexp/no-extensions_test: Crash # Instance of 'TypeOperator': type check unimpl
|
|||
regexp/pcre_test: Crash # Please triage this failure.
|
||||
regexp/range-out-of-order_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
regexp/regexp_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
set_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
set_to_string_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
splay_tree_from_iterables_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
splay_tree_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
|
@ -310,7 +309,6 @@ string_operations_with_null_test: Crash # Instance of 'TypeOperator': type check
|
|||
string_pattern_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
string_replace_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
string_runes_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
string_source_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
string_substring_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
string_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
symbol_operator_test/03: RuntimeError # Please triage this failure.
|
||||
|
|
|
@ -155,6 +155,7 @@ metadata_test: CompileTimeError # Issue 5841
|
|||
infinity_test: RuntimeError # Issue 4984
|
||||
mixin_mixin2_test: RuntimeError # Issue 13109.
|
||||
mixin_mixin3_test: RuntimeError # Issue 13109.
|
||||
mixin_mixin7_test: RuntimeError # Issue 13109.
|
||||
mixin_regress_13688_test: RuntimeError # Issue 13109.
|
||||
modulo_test: RuntimeError # Issue 15246
|
||||
truncdiv_test: RuntimeError # Issue 15246
|
||||
|
@ -218,7 +219,6 @@ regress_22443_test: Pass,RuntimeError # Issue 17458
|
|||
[ $compiler == dart2js && $cps_ir == false ]
|
||||
generic_field_mixin4_test: Crash # Issue 18651
|
||||
generic_field_mixin5_test: Crash # Issue 18651
|
||||
mixin_mixin7_test: RuntimeError # Issue 13109.
|
||||
|
||||
[ $compiler == dart2js && $cps_ir ]
|
||||
aborting_switch_case_test: Crash # (switch (42){case 42:foo();foo();break;}): Unhandled node
|
||||
|
@ -366,21 +366,6 @@ call_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nul
|
|||
call_through_null_getter_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
call_type_literal_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
cascade2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
cast2_test/01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast2_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/01: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/02: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/03: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/04: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/05: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/07: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/08: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/10: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/12: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/13: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/14: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/15: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cast_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
cha_deopt1_test: RuntimeError # Please triage this failure.
|
||||
cha_deopt2_test: RuntimeError # Please triage this failure.
|
||||
cha_deopt3_test: RuntimeError # Please triage this failure.
|
||||
|
@ -430,8 +415,6 @@ conditional_method_invocation_test/11: Crash # Instance of 'TypeOperator': type
|
|||
conditional_property_access_test/07: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
conditional_property_access_test/08: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
conditional_property_access_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
conditional_property_assignment_test/06: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
conditional_property_assignment_test/11: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
conditional_property_assignment_test/14: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
conditional_property_assignment_test/15: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
conditional_property_assignment_test/16: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
|
@ -710,17 +693,14 @@ is_nan_test: Crash # Instance of 'TypeOperator': type check unimplemented for _N
|
|||
is_not_class2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
isnot_malformed_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
issue10581_test: Crash # Unhandled node
|
||||
issue10721_test: RuntimeError # Please triage this failure.
|
||||
issue10747_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
issue10783_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
issue11724_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
issue12023_test: Crash # Unhandled node
|
||||
issue12284_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
issue12336_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
issue13474_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
issue14014_3_test: Crash # Instance of 'TypeOperator': type check unimplemented for foo<T>.
|
||||
issue20476_test: Crash # (try {try {return 1;}catch (e1){}finally {return 3;}}catch (e2){}finally {return 5;}): try/finally
|
||||
issue7525_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
issue_1751477_test: RuntimeError # Please triage this failure.
|
||||
label_test: Crash # (switch (i){case 111:while(doAgain()){break L;}default:i-- ;}): Unhandled node
|
||||
large_class_declaration_test: Crash # Please triage this failure.
|
||||
|
@ -735,7 +715,6 @@ list_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nul
|
|||
malbounded_type_cast2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
malbounded_type_cast_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
malbounded_type_test2_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
malformed2_test/00: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
malformed_inheritance_test/03: Crash # Please triage this failure.
|
||||
malformed_inheritance_test/09: Crash # Please triage this failure.
|
||||
malformed_inheritance_test/10: Crash # Please triage this failure.
|
||||
|
@ -762,8 +741,6 @@ mixin_illegal_static_access_test: Crash # Instance of 'TypeOperator': type check
|
|||
mixin_invalid_inheritance1_test/01: Crash # Please triage this failure.
|
||||
mixin_invalid_inheritance1_test/02: Crash # Please triage this failure.
|
||||
mixin_invalid_inheritance1_test/03: Crash # Please triage this failure.
|
||||
mixin_issue10216_2_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
mixin_issue10216_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
mixin_lib_extends_field_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
mixin_lib_extends_method_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
mixin_method_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
|
@ -802,7 +779,6 @@ null_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
|
|||
number_identifier_test/05: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
number_identifier_test/08: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
number_identifier_test/09: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
number_identifier_test/none: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
on_catch_malformed_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
operator_equals_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
optimized_constant_array_string_access_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
|
@ -934,7 +910,6 @@ try_catch_test/01: Crash # Please triage this failure.
|
|||
try_catch_test/none: Crash # Please triage this failure.
|
||||
type_argument_in_super_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
type_check_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
type_error_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
type_literal_prefix_call_test/00: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
type_parameter_test/01: Crash # Please triage this failure.
|
||||
type_parameter_test/02: Crash # Please triage this failure.
|
||||
|
@ -968,7 +943,6 @@ type_variable_conflict2_test/07: Crash # Instance of 'TypeOperator': type check
|
|||
type_variable_conflict2_test/09: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
type_variable_function_type_test: Crash # Instance of 'TypeOperator': type check unimplemented for Func<S>.
|
||||
type_variable_typedef_test: Crash # type expression Foo<T> (typedef)
|
||||
typed_equality_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
typedef_is_test: Crash # Instance of 'TypeOperator': type check unimplemented for Func1.
|
||||
typevariable_substitution2_test/01: Crash # Please triage this failure.
|
||||
typevariable_substitution2_test/02: Crash # Please triage this failure.
|
||||
|
|
|
@ -456,7 +456,6 @@ mirrors/hot_set_field_test: Crash # Instance of 'TypeOperator': type check unimp
|
|||
mirrors/immutable_collections_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
mirrors/inference_and_no_such_method_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
mirrors/inherit_field_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
mirrors/inherited_metadata_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
mirrors/initializing_formals_test/01: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
mirrors/initializing_formals_test/03: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
mirrors/initializing_formals_test/none: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
|
|
|
@ -237,7 +237,6 @@ io/regress_21160_test: Crash # Unhandled node
|
|||
io/secure_client_raw_server_test: Crash # Unhandled node
|
||||
io/secure_server_closing_test: Crash # Please triage this failure.
|
||||
io/secure_server_socket_test: Crash # Please triage this failure.
|
||||
io/secure_socket_alpn_test: Crash # Instance of 'TypeOperator': type casts not implemented.
|
||||
io/secure_socket_argument_test: Crash # Instance of 'TypeOperator': type check unimplemented for _Nullary.
|
||||
io/secure_socket_bad_data_test: Crash # Unhandled node
|
||||
io/skipping_dart2js_compilations_test: Crash # Unhandled node
|
||||
|
|
Loading…
Reference in a new issue