Chromium Code Reviews| Index: lib/compiler/implementation/ssa/builder.dart |
| diff --git a/lib/compiler/implementation/ssa/builder.dart b/lib/compiler/implementation/ssa/builder.dart |
| index 39512f6c67cc36287df4a3e100fb87ec911b8645..9e69a50651e97ed222040b1f237b9aaa2840db8f 100644 |
| --- a/lib/compiler/implementation/ssa/builder.dart |
| +++ b/lib/compiler/implementation/ssa/builder.dart |
| @@ -156,6 +156,7 @@ class SsaBuilderTask extends CompilerTask { |
| HGraph build(WorkItem work) { |
|
ngeoffray
2012/09/17 12:46:24
I'd really prefer if this guy did not have to care
ahe
2012/09/18 11:25:54
Agreed, ideally, the only change to this method sh
Johnni Winther
2012/09/20 08:12:23
Done.
|
| return measure(() { |
| Element element = work.element; |
| + Element implementation = element.implementation; |
| HInstruction.idCounter = 0; |
| ConstantSystem constantSystem = compiler.backend.constantSystem; |
| SsaBuilder builder = new SsaBuilder(constantSystem, this, work); |
| @@ -167,9 +168,9 @@ class SsaBuilderTask extends CompilerTask { |
| kind === ElementKind.FUNCTION || |
| kind === ElementKind.GETTER || |
| kind === ElementKind.SETTER) { |
| - graph = builder.buildMethod(work.element); |
| + graph = builder.buildMethod(implementation); |
| } else if (kind === ElementKind.FIELD) { |
| - graph = builder.buildLazyInitializer(work.element); |
| + graph = builder.buildLazyInitializer(implementation); |
| } |
| assert(graph.isValid()); |
| if (kind !== ElementKind.FIELD) { |
| @@ -183,7 +184,7 @@ class SsaBuilderTask extends CompilerTask { |
| // If there is an estimate of the parameter types assume these types when |
| // compiling. |
| OptionalParameterTypes defaultValueTypes = null; |
| - FunctionSignature signature = element.computeSignature(compiler); |
| + FunctionSignature signature = implementation.computeSignature(compiler); |
| if (signature.optionalParameterCount > 0) { |
| defaultValueTypes = |
| new OptionalParameterTypes(signature.optionalParameterCount); |
| @@ -229,7 +230,7 @@ class SsaBuilderTask extends CompilerTask { |
| HGraph compileConstructor(SsaBuilder builder, WorkItem work) { |
| // The body of the constructor will be generated in a separate function. |
| final ClassElement classElement = work.element.getEnclosingClass(); |
| - return builder.buildFactory(classElement, work.element); |
| + return builder.buildFactory(classElement, work.element.implementation); |
| } |
| } |
| @@ -340,8 +341,12 @@ class LocalsHandler { |
| updateLocal(boxElement, newBox); |
| } |
| + /** |
| + * Invariant: [function] must be the implementation element. |
|
ahe
2012/09/18 11:25:54
Not documentation.
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + */ |
| void startFunction(FunctionElement function, |
| FunctionExpression node) { |
| + assert(function.isImplementation); |
| Compiler compiler = builder.compiler; |
| closureData = compiler.closureToClassMapper.computeClosureToClassMapping( |
| node, builder.elements); |
| @@ -885,8 +890,17 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| methodInterceptionEnabled = true; |
| } |
| + /** |
| + * Invariant: [functionElement] must be the implementation element. |
|
ahe
2012/09/18 11:25:54
Not documentation.
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + */ |
| HGraph buildMethod(FunctionElement functionElement) { |
| + assert(functionElement.isImplementation); |
| FunctionExpression function = functionElement.parseNode(compiler); |
| + assert(function !== null); |
| + if (function.modifiers !== null) { |
|
ngeoffray
2012/09/17 12:46:24
Put the if in the assert
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + assert(!function.modifiers.isExternal()); |
| + } |
| + assert(elements[function] !== null); |
| openFunction(functionElement, function); |
| function.body.accept(this); |
| return closeFunction(); |
| @@ -916,10 +930,10 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| */ |
| ConstructorBodyElement getConstructorBody(FunctionElement constructor) { |
| assert(constructor.isGenerativeConstructor()); |
| + assert(constructor.isImplementation); |
| if (constructor is SynthesizedConstructorElement) return null; |
| FunctionExpression node = constructor.parseNode(compiler); |
| - // If we know the body doesn't have any code, we don't generate |
| - // it. |
| + // If we know the body doesn't have any code, we don't generate it. |
| if (node.body.asBlock() !== null) { |
| NodeList statements = node.body.asBlock().statements; |
| if (statements.isEmpty()) return null; |
| @@ -941,18 +955,24 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| if (bodyElement === null) { |
| bodyElement = new ConstructorBodyElement(constructor); |
| TreeElements treeElements = |
| - compiler.resolver.resolveMethodElement(constructor); |
| - compiler.enqueuer.codegen.addToWorkList(bodyElement, treeElements); |
| + compiler.resolver.resolveMethodElement(constructor.declaration); |
| classElement.backendMembers = |
| classElement.backendMembers.prepend(bodyElement); |
| + compiler.enqueuer.codegen.addToWorkList(bodyElement.declaration, |
| + treeElements); |
| } |
| assert(bodyElement.isGenerativeConstructorBody()); |
| return bodyElement; |
| } |
| + /** |
| + * Invariant: [function] must be the implementation element. |
|
ahe
2012/09/18 11:25:54
Not documentation.
|
| + */ |
| InliningState enterInlinedMethod(PartialFunctionElement function, |
| Selector selector, |
| Link<Node> arguments) { |
| + assert(function.isImplementation); |
| + |
| // Once we start to compile the arguments we must be sure that we don't |
| // abort. |
| List<HInstruction> compiledArguments = new List<HInstruction>(); |
| @@ -973,6 +993,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| localsHandler.updateLocal(returnElement, |
| graph.addConstantNull(constantSystem)); |
| elements = compiler.enqueuer.resolution.getCachedElements(function); |
| + assert(elements !== null); |
| FunctionSignature signature = function.computeSignature(compiler); |
| int index = 0; |
| signature.forEachParameter((Element parameter) { |
| @@ -996,9 +1017,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| stack = state.oldStack; |
| } |
| + /** |
| + * Invariant: [element] must be the implementation element. |
|
ahe
2012/09/18 11:25:54
Not documentation.
|
| + */ |
| bool tryInlineMethod(Element element, |
| Selector selector, |
| Link<Node> arguments) { |
| + assert(element.isImplementation); |
| // TODO(floitsch): we should be able to inline inside lazy initializers. |
| if (!currentElement.isFunction()) return false; |
| // TODO(floitsch): we should be able to inline getters, setters and |
| @@ -1039,11 +1064,16 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| return true; |
| } |
| + /** |
| + * Invariant: [constructor] and [constructors] must all be implementation |
|
ahe
2012/09/18 11:25:54
Not documentation.
|
| + * elements. |
| + */ |
| void inlineSuperOrRedirect(FunctionElement constructor, |
| Selector selector, |
| Link<Node> arguments, |
| List<FunctionElement> constructors, |
| Map<Element, HInstruction> fieldValues) { |
| + assert(constructor.isImplementation); |
| constructors.addLast(constructor); |
| List<HInstruction> compiledArguments = new List<HInstruction>(); |
| @@ -1087,10 +1117,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| * |
| * The constructors of the inlined initializers is added to [constructors] |
| * with sub constructors having a lower index than super constructors. |
| + * |
| + * Invariant: The [constructor] and elements in [constructors] must all be |
| + * implementation elements. |
| */ |
| void buildInitializers(FunctionElement constructor, |
| List<FunctionElement> constructors, |
| Map<Element, HInstruction> fieldValues) { |
| + assert(constructor.isImplementation); |
| FunctionExpression functionNode = constructor.parseNode(compiler); |
| bool foundSuperOrRedirect = false; |
| @@ -1128,7 +1162,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| // the class is not Object. |
| ClassElement enclosingClass = constructor.getEnclosingClass(); |
| ClassElement superClass = enclosingClass.superclass; |
| - if (enclosingClass != compiler.objectClass) { |
| + if (!enclosingClass.isObject) { |
|
ahe
2012/09/18 11:25:54
I'm not sure about the implementation of this.
Johnni Winther
2012/09/20 08:12:23
Changed.
|
| assert(superClass !== null); |
| assert(superClass.resolutionState == STATE_DONE); |
| Selector selector = |
| @@ -1137,7 +1171,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| if (target === null) { |
| compiler.internalError("no default constructor available"); |
| } |
| - inlineSuperOrRedirect(target, |
| + inlineSuperOrRedirect(target.implementation, |
| selector, |
| const EmptyLink<Node>(), |
| constructors, |
| @@ -1149,9 +1183,12 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| /** |
| * Run through the fields of [cls] and add their potential |
| * initializers. |
| + * |
| + * Invariant: [classElement] must be the declaration element. |
| */ |
| void buildFieldInitializers(ClassElement classElement, |
| Map<Element, HInstruction> fieldValues) { |
| + assert(classElement.isDeclaration); |
| classElement.forEachInstanceField( |
| includeBackendMembers: true, |
| includeSuperMembers: false, |
| @@ -1183,9 +1220,14 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| * to, starting from the current constructor. |
| * - Call the the constructor bodies, starting from the constructor(s) in the |
| * super class(es). |
| + * |
| + * Invariants: [classElement] must be the declaration element, and |
| + * [functionElement] must be the implementation element. |
| */ |
| HGraph buildFactory(ClassElement classElement, |
| FunctionElement functionElement) { |
| + assert(classElement.isDeclaration); |
| + assert(functionElement.isImplementation); |
| FunctionExpression function = functionElement.parseNode(compiler); |
| // Note that constructors (like any other static function) do not need |
| // to deal with optional arguments. It is the callers job to provide all |
| @@ -1243,18 +1285,21 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| // Generate calls to the constructor bodies. |
| for (int index = constructors.length - 1; index >= 0; index--) { |
| FunctionElement constructor = constructors[index]; |
| + assert(constructor.isImplementation); |
| ConstructorBodyElement body = getConstructorBody(constructor); |
| if (body === null) continue; |
| List bodyCallInputs = <HInstruction>[]; |
| bodyCallInputs.add(newObject); |
| - int arity = body.functionSignature.parameterCount; |
| - body.functionSignature.forEachParameter((parameter) { |
| + FunctionSignature functionSignature = body.computeSignature(compiler); |
| + int arity = functionSignature.parameterCount; |
| + functionSignature.forEachParameter((parameter) { |
| bodyCallInputs.add(localsHandler.readLocal(parameter)); |
| }); |
| // TODO(ahe): The constructor name is statically resolved. See |
| // SsaCodeGenerator.visitInvokeDynamicMethod. Is there a cleaner |
| // way to do this? |
| - SourceString name = new SourceString(backend.namer.getName(body)); |
| + SourceString name = |
| + new SourceString(backend.namer.getName(body.declaration)); |
| // TODO(kasperl): This seems fishy. We shouldn't be inventing all |
| // these selectors. Maybe the resolver can do more of the work |
| // for us here? |
| @@ -1312,8 +1357,12 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| localsHandler.updateLocal(checkResultElement, check); |
| } |
| + /** |
| + * Invariant: [functionElement] must be the implementation element. |
|
ahe
2012/09/18 11:25:54
Not documentation.
|
| + */ |
| void openFunction(FunctionElement functionElement, |
| FunctionExpression node) { |
| + assert(functionElement.isImplementation); |
| HBasicBlock block = graph.addNewBlock(); |
| open(graph.entry); |
| @@ -2038,7 +2087,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } else if (element.isField() && compiler.isLazilyInitialized(element)) { |
| push(new HLazyStatic(element)); |
| } else { |
| - push(new HStatic(element)); |
| + push(new HStatic(element.declaration)); |
|
ngeoffray
2012/09/17 12:46:24
Why this change?
Johnni Winther
2012/09/20 08:12:23
For some reason putting the invariant on the eleme
|
| if (element.isGetter()) { |
| push(new HInvokeStatic(<HInstruction>[pop()])); |
| } |
| @@ -2047,7 +2096,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| HInstruction receiver = generateInstanceSendReceiver(send); |
| generateInstanceGetterWithCompiledReceiver(send, receiver); |
| } else if (Elements.isStaticOrTopLevelFunction(element)) { |
| - push(new HStatic(element)); |
| + push(new HStatic(element.declaration)); |
| // TODO(ahe): This should be registered in codegen. |
| compiler.enqueuer.codegen.registerGetOfStaticFunction(element); |
| } else if (Elements.isErroneousElement(element)) { |
| @@ -2267,11 +2316,15 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| /** |
| * Returns true if the arguments were compatible with the function signature. |
| + * |
| + * Invariant: [element] must be the implementation element. |
| */ |
| bool addStaticSendArgumentsToList(Selector selector, |
| Link<Node> arguments, |
| FunctionElement element, |
| List<HInstruction> list) { |
| + assert(element.isImplementation); |
| + |
| HInstruction compileArgument(Node argument) { |
| visit(argument); |
| return pop(); |
| @@ -2489,7 +2542,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| node: closure); |
| } |
| FunctionElement function = element; |
| - FunctionSignature params = function.computeSignature(compiler); |
| + FunctionSignature params |
| + = function.implementation.computeSignature(compiler); |
| if (params.optionalParameterCount !== 0) { |
| compiler.cancel( |
| 'JS_TO_CLOSURE does not handle closure with optional parameters', |
| @@ -2556,7 +2610,7 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| Selector selector = elements.getSelector(node); |
| Element element = elements[node]; |
| if (element === null) return generateSuperNoSuchMethodSend(node); |
| - HInstruction target = new HStatic(element); |
| + HInstruction target = new HStatic(element.declaration); |
| HInstruction context = localsHandler.readThis(); |
| add(target); |
| var inputs = <HInstruction>[target, context]; |
| @@ -2564,7 +2618,8 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| push(new HInvokeSuper(inputs)); |
| } else if (element.isFunction() || element.isGenerativeConstructor()) { |
| bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| - element, inputs); |
| + element.implementation, |
| + inputs); |
| if (!succeeded) { |
| // TODO(ngeoffray): Match the VM behavior and throw an |
| // exception at runtime. |
| @@ -2672,12 +2727,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } |
| FunctionElement functionElement = constructor; |
| constructor = functionElement.defaultImplementation; |
| - HInstruction target = new HStatic(constructor); |
| + HInstruction target = new HStatic(constructor.declaration); |
| add(target); |
| var inputs = <HInstruction>[]; |
| inputs.add(target); |
| bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| - constructor, inputs); |
| + constructor.implementation, |
| + inputs); |
| if (!succeeded) { |
| // TODO(ngeoffray): Match the VM behavior and throw an |
| // exception at runtime. |
| @@ -2719,13 +2775,13 @@ class SsaBuilder extends ResolvedVisitor implements Visitor { |
| } |
| compiler.ensure(!element.isGenerativeConstructor()); |
| if (element.isFunction()) { |
| - if (tryInlineMethod(element, selector, node.arguments)) return; |
| + if (tryInlineMethod(element.implementation, selector, node.arguments)) return; |
|
ngeoffray
2012/09/17 12:46:24
line too long
Johnni Winther
2012/09/20 08:12:23
Done.
|
| HInstruction target = new HStatic(element); |
| add(target); |
| var inputs = <HInstruction>[target]; |
| bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| - element, inputs); |
| + element.implementation, inputs); |
|
ngeoffray
2012/09/17 12:46:24
ditto
Johnni Winther
2012/09/20 08:12:23
Done.
|
| if (!succeeded) { |
| // TODO(ngeoffray): Match the VM behavior and throw an |
| // exception at runtime. |
| @@ -3931,6 +3987,7 @@ class InlineWeeder extends AbstractVisitor { |
| } |
| class InliningState { |
| + /// Invariant: [function] must be the implementation element. |
| final PartialFunctionElement function; |
| final Element oldReturnElement; |
| final TreeElements oldElements; |
| @@ -3939,7 +3996,9 @@ class InliningState { |
| InliningState(this.function, |
| this.oldReturnElement, |
| this.oldElements, |
| - this.oldStack); |
| + this.oldStack) { |
| + assert(function.isImplementation); |
| + } |
| } |
| class SsaBranch { |