Chromium Code Reviews| 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 cc97bab5b70e7c99370812ea2f3837af4e356769..fc1bd9d30d0d129fedd9690e5ae12abc73a10004 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart |
| @@ -361,8 +361,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)) { |
| @@ -1097,13 +1104,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)) { |
| @@ -1124,6 +1124,16 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } |
| } |
| + // Check the type of the arguments. This must be done after setting up the |
| + // type variables in the [localsHandler] because the checked types may |
| + // contain type variables. |
| + FunctionSignature signature = function.computeSignature(compiler); |
| + signature.orderedForEachParameter((Element parameter) { |
| + HInstruction argument = compiledArguments[argumentIndex++]; |
| + 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, |
| @@ -1214,6 +1224,15 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| if (!canBeInlined) return false; |
| } |
| + // We cannot inline methods with type variables in the signature in checked |
| + // mode, because we currently do not have access to the type variables |
| + // through the locals. |
| + // TODO(karlklose): remove this and enable inlining of these methods. |
| + if (compiler.enableTypeAssertions && |
| + element.computeType(compiler).containsTypeVariables) { |
| + return false; |
| + } |
| + |
| assert(canBeInlined); |
| InliningState state = enterInlinedMethod( |
| function, selector, argumentsNodes, providedArguments, currentNode); |
| @@ -1668,6 +1687,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); |
| @@ -1704,24 +1735,37 @@ 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) { |
| + if (type == null) return original; |
| + if (identical(type.element, compiler.dynamicClass)) return original; |
| + if (identical(type.element, compiler.objectClass)) return original; |
|
ngeoffray
2013/05/15 08:45:33
Can you remove those two checks above? They should
karlklose
2013/05/15 12:59:16
Removed. They will always end up calling convertTy
|
| + if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) { |
| + 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 if (type.kind == TypeKind.TYPE_VARIABLE) { |
| + HType subtype = original.instructionType; |
| + HInstruction typeVariable = addTypeVariableReference(type); |
| + return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
| + original, typeVariable); |
| + } else { |
| + return original.convertType(compiler, type, kind); |
| } |
| } |
| - 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; |
| } |
| @@ -2589,7 +2633,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); |
| @@ -2605,8 +2650,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 +2816,35 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } else { |
| generateRuntimeError(node, '$type is malformed: $reasons'); |
| } |
| - return; |
| + } else { |
| + 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.getCheckSubtypeOfRuntimeType(); |
| 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 +2860,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) { |
| @@ -4730,7 +4777,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); |
| } |
| } |