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

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 13019003: Enable full type-checks in checked mode. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use HTypeConversion instead of HIs. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/ssa/builder.dart
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index c7798ce04c1766d86e7ebdfac705c4c3c8a10fc8..e810b2c6ee80c14ab1bf99bfa6b04079a0fd69f6 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -360,8 +360,15 @@ class LocalsHandler {
HInstruction readLocal(Element element) {
if (isAccessedDirectly(element)) {
if (directLocals[element] == null) {
- builder.compiler.internalError("Cannot find value $element",
- element: element);
+ if (element.isTypeVariable()) {
+ builder.compiler.internalError(
+ "Runtime type information not available for $element",
+ element: builder.compiler.currentElement);
+ } else {
+ builder.compiler.internalError(
+ "Cannot find value $element",
+ element: element);
+ }
}
return directLocals[element];
} else if (isStoredInClosureField(element)) {
@@ -1096,13 +1103,6 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
compiledArguments[argumentIndex++]);
}
- FunctionSignature signature = function.computeSignature(compiler);
- signature.orderedForEachParameter((Element parameter) {
- HInstruction argument = compiledArguments[argumentIndex++];
- newLocalsHandler.updateLocal(parameter, argument);
- potentiallyCheckType(argument, parameter.computeType(compiler));
- });
-
if (function.isConstructor()) {
ClassElement enclosing = function.getEnclosingClass();
if (backend.needsRti(enclosing)) {
@@ -1123,6 +1123,15 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
}
+ FunctionSignature signature = function.computeSignature(compiler);
ngeoffray 2013/05/13 09:10:59 Also add a similar comment to line 1675 here.
karlklose 2013/05/14 13:49:41 Done.
+ int index = 0;
+ if (isInstanceMember) index++;
ngeoffray 2013/05/13 09:10:59 Why not using argumentIndex?
karlklose 2013/05/14 13:49:41 Done.
+ signature.orderedForEachParameter((Element parameter) {
+ HInstruction argument = compiledArguments[index++];
+ newLocalsHandler.updateLocal(parameter, argument);
+ potentiallyCheckType(argument, parameter.computeType(compiler));
+ });
+
// TODO(kasperl): Bad smell. We shouldn't be constructing elements here.
returnElement = new ElementX(const SourceString("result"),
ElementKind.VARIABLE,
@@ -1205,6 +1214,12 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
if (!canBeInlined) return false;
}
+ // TODO(karlklose): remove this and enable inlining of these methods.
ngeoffray 2013/05/13 09:10:59 Could you also explain why it does not work?
karlklose 2013/05/14 13:49:41 Done.
+ if (compiler.enableTypeAssertions &&
+ element.computeType(compiler).containsTypeVariables) {
+ return false;
+ }
+
assert(canBeInlined);
InliningState state = enterInlinedMethod(
function, selector, argumentsNodes, providedArguments, currentNode);
@@ -1657,6 +1672,18 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
open(block);
+ // Add the type parameters of the class as parameters of this method. This
+ // must be done before adding the normal parameters, because their types
+ // may contain references to type variables.
+ var enclosing = element.enclosingElement;
+ if ((element.isConstructor() || element.isGenerativeConstructorBody())
+ && backend.needsRti(enclosing)) {
+ enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
+ HParameterValue param = addParameter(typeVariable.element);
+ localsHandler.directLocals[typeVariable.element] = param;
+ });
+ }
+
if (element is FunctionElement) {
FunctionElement functionElement = element;
FunctionSignature signature = functionElement.computeSignature(compiler);
@@ -1693,24 +1720,43 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
// Otherwise it is a lazy initializer which does not have parameters.
assert(element is VariableElement);
}
+ }
- // Add the type parameters of the class as parameters of this
- // method.
- var enclosing = element.enclosingElement;
- if ((element.isConstructor() || element.isGenerativeConstructorBody())
- && backend.needsRti(enclosing)) {
- enclosing.typeVariables.forEach((TypeVariableType typeVariable) {
- HParameterValue param = addParameter(typeVariable.element);
- localsHandler.directLocals[typeVariable.element] = param;
- });
+ HInstruction buildTypeConversion(Compiler compiler, HInstruction original,
+ DartType type, int kind) {
ngeoffray 2013/05/13 09:10:59 Please do not duplicate what's already in convertT
karlklose 2013/05/14 13:49:41 There are users in the optimizer, but they cannot
+ if (type == null) return original;
+ if (identical(type.element, compiler.dynamicClass)) return original;
+ if (identical(type.element, compiler.objectClass)) return original;
+ if (type.isMalformed || (type.kind != TypeKind.INTERFACE &&
+ type.kind != TypeKind.TYPE_VARIABLE)) {
+ return new HTypeConversion(type, kind, HType.UNKNOWN, original);
+ } else if (kind == HTypeConversion.BOOLEAN_CONVERSION_CHECK) {
+ // Boolean conversion checks work on non-nullable booleans.
+ return new HTypeConversion(type, kind, HType.BOOLEAN, original);
+ }
+ if (type.kind == TypeKind.INTERFACE) {
+ HType subtype = new HType.subtype(type, compiler);
+ if (type.isRaw) {
+ return new HTypeConversion(type, kind, subtype, original);
+ }
+ HInstruction representations = buildTypeArgumentRepresentations(type);
+ add(representations);
+ return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
+ original, representations);
+ } else {
+ HType subtype = original.instructionType;
+ assert(type.kind == TypeKind.TYPE_VARIABLE);
ngeoffray 2013/05/13 09:10:59 Move that assert one up.
karlklose 2013/05/14 13:49:41 This assert is obsolete now.
+ HInstruction typeVariable = addTypeVariableReference(type);
+ return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
+ original, typeVariable);
}
}
- HInstruction potentiallyCheckType(
- HInstruction original, DartType type,
+ HInstruction potentiallyCheckType(HInstruction original, DartType type,
{ int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
if (!compiler.enableTypeAssertions) return original;
- HInstruction other = original.convertType(compiler, type, kind);
+ HInstruction other =
+ buildTypeConversion(compiler, original, type, kind);
if (other != original) add(other);
return other;
}
@@ -2584,7 +2630,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
<HInstruction>[target, value], HType.UNKNOWN);
addWithPosition(instruction, location);
} else {
- value = potentiallyCheckType(value, element.computeType(compiler));
+ value =
+ potentiallyCheckType(value, element.computeType(compiler));
addWithPosition(new HStaticStore(element, value), location);
}
stack.add(value);
@@ -2600,8 +2647,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
if (value.sourceElement == null) {
value.sourceElement = element;
}
- HInstruction checked = potentiallyCheckType(
- value, element.computeType(compiler));
+ HInstruction checked =
+ potentiallyCheckType(value, element.computeType(compiler));
if (!identical(checked, value)) {
pop();
stack.add(checked);
@@ -2771,28 +2818,35 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
} else {
generateRuntimeError(node, '$type is malformed: $reasons');
}
- return;
+ } else {
ngeoffray 2013/05/13 09:10:59 You don't need this change anymore.
karlklose 2013/05/14 13:49:41 I know, but I think it reads better. In particular
+ HInstruction instruction = buildIsNode(node, type, expression);
+ if (isNot) {
+ add(instruction);
+ instruction = new HNot(instruction);
+ }
+ push(instruction);
}
+ }
- HInstruction instruction;
+ HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
if (type.kind == TypeKind.TYPE_VARIABLE) {
HInstruction runtimeType = addTypeVariableReference(type);
- Element helper = backend.getGetObjectIsSubtype();
+ Element helper = backend.getObjectIsSubtype();
HInstruction helperCall = new HStatic(helper);
add(helperCall);
List<HInstruction> inputs = <HInstruction>[helperCall, expression,
runtimeType];
HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN);
add(call);
- instruction = new HIs(type, <HInstruction>[expression, call],
- HIs.VARIABLE_CHECK);
+ return new HIs(type, <HInstruction>[expression, call],
+ HIs.VARIABLE_CHECK);
} else if (RuntimeTypes.hasTypeArguments(type)) {
Element element = type.element;
Element helper = backend.getCheckSubtype();
HInstruction helperCall = new HStatic(helper);
add(helperCall);
HInstruction representations =
- buildTypeArgumentRepresentations(type);
+ buildTypeArgumentRepresentations(type);
add(representations);
String operator =
backend.namer.operatorIs(backend.getImplementationClass(element));
@@ -2808,16 +2862,11 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
asFieldName];
HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN);
add(call);
- instruction = new HIs(type, <HInstruction>[expression, call],
- HIs.COMPOUND_CHECK);
+ return
+ new HIs(type, <HInstruction>[expression, call], HIs.COMPOUND_CHECK);
} else {
- instruction = new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK);
- }
- if (isNot) {
- add(instruction);
- instruction = new HNot(instruction);
+ return new HIs(type, <HInstruction>[expression], HIs.RAW_CHECK);
}
- push(instruction);
}
void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) {
@@ -4719,7 +4768,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor {
}
// TODO(karlkose): support type arguments here.
condition = new HIs(type, <HInstruction>[unwrappedException],
- HIs.RAW_CHECK, nullOk: true);
+ HIs.RAW_CHECK);
push(condition);
}
}

Powered by Google App Engine
This is Rietveld 408576698