| Index: lib/compiler/implementation/ssa/builder.dart
|
| ===================================================================
|
| --- lib/compiler/implementation/ssa/builder.dart (revision 7371)
|
| +++ lib/compiler/implementation/ssa/builder.dart (working copy)
|
| @@ -305,8 +305,9 @@
|
|
|
| FunctionParameters params = function.computeParameters(builder.compiler);
|
| params.forEachParameter((Element element) {
|
| - HParameterValue parameter = new HParameterValue(element);
|
| + HInstruction parameter = new HParameterValue(element);
|
| builder.add(parameter);
|
| + parameter = builder.potentiallyCheckType(parameter, element);
|
| directLocals[element] = parameter;
|
| });
|
|
|
| @@ -1031,6 +1032,34 @@
|
| open(block);
|
| }
|
|
|
| + HInstruction potentiallyCheckType(HInstruction original,
|
| + Element sourceElement) {
|
| + if (!compiler.enableTypeAssertions) return original;
|
| +
|
| + Type type = sourceElement.computeType(compiler);
|
| + if (type === null) return original;
|
| + if (type.element === compiler.dynamicClass) return original;
|
| + if (type.element === compiler.objectClass) return original;
|
| +
|
| + HType convertedType = new HType.fromBoundedType(type, compiler, true);
|
| +
|
| + // TODO(ngeoffray): the factory method should never return null.
|
| + if (convertedType === null) {
|
| + return original;
|
| + }
|
| +
|
| + // No need to convert if we know the instruction has
|
| + // [convertedType] as a bound.
|
| + if (original.guaranteedType == convertedType) {
|
| + return original;
|
| + }
|
| +
|
| + HInstruction instruction =
|
| + new HTypeConversion(convertedType, original, true);
|
| + add(instruction);
|
| + return instruction;
|
| + }
|
| +
|
| HGraph closeFunction() {
|
| // TODO(kasperl): Make this goto an implicit return.
|
| if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit);
|
| @@ -1795,12 +1824,17 @@
|
| HInstruction receiver = generateInstanceSendReceiver(send);
|
| generateInstanceSetterWithCompiledReceiver(send, receiver, value);
|
| } else {
|
| - localsHandler.updateLocal(element, value);
|
| stack.add(value);
|
| // If the value does not already have a name, give it here.
|
| if (value.sourceElement === null) {
|
| value.sourceElement = element;
|
| }
|
| + HInstruction checked = potentiallyCheckType(value, element);
|
| + if (checked !== value) {
|
| + pop();
|
| + stack.add(checked);
|
| + }
|
| + localsHandler.updateLocal(element, checked);
|
| }
|
| }
|
|
|
|
|