Index: pkg/compiler/lib/src/ssa/builder.dart |
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart |
index aa3b7f098766afe850e43dfd89691adfbd52c189..abd5e29594869b5486b149f52854b583ddcb859b 100644 |
--- a/pkg/compiler/lib/src/ssa/builder.dart |
+++ b/pkg/compiler/lib/src/ssa/builder.dart |
@@ -1006,9 +1006,6 @@ class SsaBuilder extends ResolvedVisitor { |
// implementation/declaration distinction. |
Element get sourceElement => sourceElementStack.last; |
- bool get _checkOrTrustTypes => |
- compiler.enableTypeAssertions || compiler.trustTypeAnnotations; |
- |
HBasicBlock addNewBlock() { |
HBasicBlock block = graph.addNewBlock(); |
// If adding a new block during building of an expression, it is due to |
@@ -1486,7 +1483,8 @@ class SsaBuilder extends ResolvedVisitor { |
// If the method is intercepted, we want the actual receiver |
// to be the first parameter. |
graph.entry.addBefore(graph.entry.last, parameter); |
- HInstruction value = potentiallyCheckOrTrustType(parameter, field.type); |
+ HInstruction value = |
+ potentiallyCheckType(parameter, field.type); |
add(new HFieldSet(field, thisInstruction, value)); |
return closeFunction(); |
} |
@@ -1497,7 +1495,7 @@ class SsaBuilder extends ResolvedVisitor { |
assert(variable.initializer != null); |
visit(variable.initializer); |
HInstruction value = pop(); |
- value = potentiallyCheckOrTrustType(value, variable.type); |
+ value = potentiallyCheckType(value, variable.type); |
closeAndGotoExit(new HReturn(value)); |
return closeFunction(); |
} |
@@ -1660,12 +1658,12 @@ class SsaBuilder extends ResolvedVisitor { |
* function. |
*/ |
void potentiallyCheckInlinedParameterTypes(FunctionElement function) { |
- if (!_checkOrTrustTypes) return; |
+ if (!compiler.enableTypeAssertions) return; |
FunctionSignature signature = function.functionSignature; |
signature.orderedForEachParameter((ParameterElement parameter) { |
HInstruction argument = localsHandler.readLocal(parameter); |
- potentiallyCheckOrTrustType(argument, parameter.type); |
+ potentiallyCheckType(argument, parameter.type); |
}); |
} |
@@ -1976,7 +1974,7 @@ class SsaBuilder extends ResolvedVisitor { |
} else { |
fields.add(member); |
DartType type = localsHandler.substInContext(member.type); |
- constructorArguments.add(potentiallyCheckOrTrustType(value, type)); |
+ constructorArguments.add(potentiallyCheckType(value, type)); |
} |
}, |
includeSuperAndInjectedMembers: true); |
@@ -2221,7 +2219,7 @@ class SsaBuilder extends ResolvedVisitor { |
// |
// Only the final target is allowed to check for the argument types. |
newParameter = |
- potentiallyCheckOrTrustType(newParameter, parameterElement.type); |
+ potentiallyCheckType(newParameter, parameterElement.type); |
} |
localsHandler.directLocals[parameterElement] = newParameter; |
}); |
@@ -2298,43 +2296,25 @@ class SsaBuilder extends ResolvedVisitor { |
} |
} |
- HInstruction _trustType(HInstruction original, DartType type) { |
- assert(compiler.trustTypeAnnotations); |
- assert(type != null); |
+ HInstruction potentiallyBuildTypeHint(HInstruction original, DartType type) { |
+ if (!compiler.trustTypeAnnotations || type == null) return original; |
type = localsHandler.substInContext(type); |
- type = type.unalias(compiler); |
- if (type.isDynamic) return original; |
if (!type.isInterfaceType) return original; |
- // The type element is either a class or the void element. |
- Element element = type.element; |
- if (element == compiler.objectClass) return original; |
- TypeMask mask = new TypeMask.subtype(element, compiler.world); |
- return new HTypeKnown.pinned(mask, original); |
+ TypeMask mask = new TypeMask.subtype(type.element, compiler.world); |
+ var result = new HTypeKnown.pinned(mask, original); |
+ return result; |
} |
- HInstruction _checkType(HInstruction original, DartType type, int kind) { |
- assert(compiler.enableTypeAssertions); |
- assert(type != null); |
+ HInstruction potentiallyCheckType(HInstruction original, DartType type, |
+ { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { |
+ if (!compiler.enableTypeAssertions) return original; |
type = localsHandler.substInContext(type); |
HInstruction other = buildTypeConversion(original, type, kind); |
+ if (other != original) add(other); |
registry.registerIsCheck(type); |
return other; |
} |
- HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type, |
- { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { |
- if (type == null) return original; |
- HInstruction checkedOrTrusted = original; |
- if (compiler.trustTypeAnnotations) { |
- checkedOrTrusted = _trustType(original, type); |
- } else if (compiler.enableTypeAssertions) { |
- checkedOrTrusted = _checkType(original, type, kind); |
- } |
- if (checkedOrTrusted == original) return original; |
- add(checkedOrTrusted); |
- return checkedOrTrusted; |
- } |
- |
void assertIsSubtype(ast.Node node, DartType subtype, DartType supertype, |
String message) { |
HInstruction subtypeInstruction = |
@@ -2378,8 +2358,8 @@ class SsaBuilder extends ResolvedVisitor { |
HInstruction popBoolified() { |
HInstruction value = pop(); |
- if (_checkOrTrustTypes) { |
- return potentiallyCheckOrTrustType( |
+ if (compiler.enableTypeAssertions) { |
+ return potentiallyCheckType( |
value, |
compiler.boolClass.rawType, |
kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
@@ -3206,7 +3186,8 @@ class SsaBuilder extends ResolvedVisitor { |
pop(); |
} else { |
VariableElement field = element; |
- value = potentiallyCheckOrTrustType(value, field.type); |
+ value = |
+ potentiallyCheckType(value, field.type); |
addWithPosition(new HStaticStore(element, value), location); |
} |
stack.add(value); |
@@ -3224,14 +3205,20 @@ class SsaBuilder extends ResolvedVisitor { |
if (value.sourceElement == null) { |
value.sourceElement = local; |
} |
- HInstruction checkedOrTrusted = |
- potentiallyCheckOrTrustType(value, local.type); |
- if (!identical(checkedOrTrusted, value)) { |
+ HInstruction checked = |
+ potentiallyCheckType(value, local.type); |
+ if (!identical(checked, value)) { |
+ pop(); |
+ stack.add(checked); |
+ } |
+ HInstruction trusted = |
+ potentiallyBuildTypeHint(checked, local.type); |
+ if (!identical(trusted, checked)) { |
pop(); |
- stack.add(checkedOrTrusted); |
+ push(trusted); |
} |
- localsHandler.updateLocal(local, checkedOrTrusted); |
+ localsHandler.updateLocal(local, trusted); |
} |
} |
@@ -4317,7 +4304,7 @@ class SsaBuilder extends ResolvedVisitor { |
// Finally, if we called a redirecting factory constructor, check the type. |
if (isRedirected) { |
- HInstruction checked = potentiallyCheckOrTrustType(newInstance, type); |
+ HInstruction checked = potentiallyCheckType(newInstance, type); |
if (checked != newInstance) { |
pop(); |
stack.add(checked); |
@@ -5055,7 +5042,7 @@ class SsaBuilder extends ResolvedVisitor { |
} else { |
visit(node.expression); |
value = pop(); |
- value = potentiallyCheckOrTrustType(value, returnType); |
+ value = potentiallyCheckType(value, returnType); |
} |
handleInTryStatement(); |