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 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); |
| } |
| } |