Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 class Interceptors { | 5 class Interceptors { |
| 6 Compiler compiler; | 6 Compiler compiler; |
| 7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
| 8 | 8 |
| 9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
| 10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || | 166 } else if (kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY || |
| 167 kind === ElementKind.FUNCTION || | 167 kind === ElementKind.FUNCTION || |
| 168 kind === ElementKind.GETTER || | 168 kind === ElementKind.GETTER || |
| 169 kind === ElementKind.SETTER) { | 169 kind === ElementKind.SETTER) { |
| 170 graph = builder.buildMethod(work.element); | 170 graph = builder.buildMethod(work.element); |
| 171 } else if (kind === ElementKind.FIELD) { | 171 } else if (kind === ElementKind.FIELD) { |
| 172 graph = builder.buildLazyInitializer(work.element); | 172 graph = builder.buildLazyInitializer(work.element); |
| 173 } | 173 } |
| 174 assert(graph.isValid()); | 174 assert(graph.isValid()); |
| 175 if (kind !== ElementKind.FIELD) { | 175 if (kind !== ElementKind.FIELD) { |
| 176 FunctionElement functionElement = element; | |
| 176 bool inLoop = functionsCalledInLoop.contains(element); | 177 bool inLoop = functionsCalledInLoop.contains(element); |
| 177 if (!inLoop) { | 178 if (!inLoop) { |
| 178 Selector selector = selectorsCalledInLoop[element.name]; | 179 Selector selector = selectorsCalledInLoop[element.name]; |
| 179 inLoop = selector !== null && selector.applies(element, compiler); | 180 inLoop = selector !== null && selector.applies(element, compiler); |
| 180 } | 181 } |
| 181 graph.calledInLoop = inLoop; | 182 graph.calledInLoop = inLoop; |
| 182 | 183 |
| 183 // If there is an estimate of the parameter types assume these types whe n | 184 // If there is an estimate of the parameter types assume these types whe n |
|
kasperl
2012/09/10 13:44:29
Long line. NYF.
floitsch
2012/10/09 16:06:44
Has been fixed in the mean-time.
| |
| 184 // compiling. | 185 // compiling. |
| 185 OptionalParameterTypes defaultValueTypes = null; | 186 OptionalParameterTypes defaultValueTypes = null; |
| 186 FunctionSignature signature = element.computeSignature(compiler); | 187 FunctionSignature signature = |
| 188 functionElement.computeSignature(compiler); | |
| 187 if (signature.optionalParameterCount > 0) { | 189 if (signature.optionalParameterCount > 0) { |
| 188 defaultValueTypes = | 190 defaultValueTypes = |
| 189 new OptionalParameterTypes(signature.optionalParameterCount); | 191 new OptionalParameterTypes(signature.optionalParameterCount); |
| 190 int index = 0; | 192 int index = 0; |
| 191 signature.forEachOptionalParameter((Element parameter) { | 193 signature.forEachOptionalParameter((Element parameter) { |
| 192 Constant defaultValue = compiler.compileVariable(parameter); | 194 Constant defaultValue = compiler.compileVariable(parameter); |
| 193 HType type = HGraph.mapConstantTypeToSsaType(defaultValue); | 195 HType type = HGraph.mapConstantTypeToSsaType(defaultValue); |
| 194 defaultValueTypes.update(index, parameter.name, type); | 196 defaultValueTypes.update(index, parameter.name, type); |
| 195 index++; | 197 index++; |
| 196 }); | 198 }); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 // [readLocal] uses the [boxElement] to find its box. By replacing it | 335 // [readLocal] uses the [boxElement] to find its box. By replacing it |
| 334 // behind its back we can still get to the old values. | 336 // behind its back we can still get to the old values. |
| 335 updateLocal(boxElement, oldBox); | 337 updateLocal(boxElement, oldBox); |
| 336 HInstruction oldValue = readLocal(boxedVariable); | 338 HInstruction oldValue = readLocal(boxedVariable); |
| 337 updateLocal(boxElement, newBox); | 339 updateLocal(boxElement, newBox); |
| 338 updateLocal(boxedVariable, oldValue); | 340 updateLocal(boxedVariable, oldValue); |
| 339 } | 341 } |
| 340 updateLocal(boxElement, newBox); | 342 updateLocal(boxElement, newBox); |
| 341 } | 343 } |
| 342 | 344 |
| 343 void startFunction(FunctionElement function, | 345 void startFunction(Element element, Expression node) { |
| 344 FunctionExpression node) { | |
| 345 Compiler compiler = builder.compiler; | 346 Compiler compiler = builder.compiler; |
| 346 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( | 347 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 347 node, builder.elements); | 348 element, node, builder.elements); |
| 348 FunctionSignature signature = function.computeSignature(compiler); | 349 |
| 349 signature.forEachParameter((Element element) { | 350 if (element is FunctionElement) { |
| 350 HInstruction parameter = new HParameterValue(element); | 351 FunctionElement functionElement = element; |
| 351 builder.add(parameter); | 352 FunctionSignature params = functionElement.computeSignature(compiler); |
| 352 builder.parameters[element] = parameter; | 353 params.forEachParameter((Element parameterElement) { |
| 353 directLocals[element] = parameter; | 354 HInstruction parameter = new HParameterValue(parameterElement); |
| 354 parameter.guaranteedType = | 355 builder.add(parameter); |
| 355 builder.mapInferredType(typesTask.getGuaranteedTypeOfElement(element)); | 356 builder.parameters[parameterElement] = parameter; |
| 356 }); | 357 directLocals[parameterElement] = parameter; |
| 358 parameter.guaranteedType = | |
| 359 builder.mapInferredType( | |
| 360 typesTask.getGuaranteedTypeOfElement(parameterElement)); | |
| 361 }); | |
| 362 } | |
| 357 | 363 |
| 358 enterScope(node); | 364 enterScope(node); |
| 359 | 365 |
| 360 // If the freeVariableMapping is not empty, then this function was a | 366 // If the freeVariableMapping is not empty, then this function was a |
| 361 // nested closure that captures variables. Redirect the captured | 367 // nested closure that captures variables. Redirect the captured |
| 362 // variables to fields in the closure. | 368 // variables to fields in the closure. |
| 363 closureData.freeVariableMapping.forEach((Element from, Element to) { | 369 closureData.freeVariableMapping.forEach((Element from, Element to) { |
| 364 redirectElement(from, to); | 370 redirectElement(from, to); |
| 365 }); | 371 }); |
| 366 if (closureData.isClosure()) { | 372 if (closureData.isClosure()) { |
| 367 // Inside closure redirect references to itself to [:this:]. | 373 // Inside closure redirect references to itself to [:this:]. |
| 368 HInstruction thisInstruction = new HThis(); | 374 HInstruction thisInstruction = new HThis(); |
| 369 builder.add(thisInstruction); | 375 builder.add(thisInstruction); |
| 370 updateLocal(closureData.closureElement, thisInstruction); | 376 updateLocal(closureData.closureElement, thisInstruction); |
| 371 } else if (function.isInstanceMember() | 377 } else if (element.isInstanceMember() |
| 372 || function.isGenerativeConstructor()) { | 378 || element.isGenerativeConstructor()) { |
| 373 // Once closures have been mapped to classes their instance members might | 379 // Once closures have been mapped to classes their instance members might |
| 374 // not have any thisElement if the closure was created inside a static | 380 // not have any thisElement if the closure was created inside a static |
| 375 // context. | 381 // context. |
| 376 ClassElement cls = function.getEnclosingClass(); | 382 ClassElement cls = element.getEnclosingClass(); |
| 377 DartType type = cls.computeType(builder.compiler); | 383 DartType type = cls.computeType(builder.compiler); |
| 378 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); | 384 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); |
| 379 builder.add(thisInstruction); | 385 builder.add(thisInstruction); |
| 380 directLocals[closureData.thisElement] = thisInstruction; | 386 directLocals[closureData.thisElement] = thisInstruction; |
| 381 } | 387 } |
| 382 } | 388 } |
| 383 | 389 |
| 384 bool hasValueForDirectLocal(Element element) { | 390 bool hasValueForDirectLocal(Element element) { |
| 385 assert(element !== null); | 391 assert(element !== null); |
| 386 assert(isAccessedDirectly(element)); | 392 assert(isAccessedDirectly(element)); |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 } | 889 } |
| 884 | 890 |
| 885 HGraph buildMethod(FunctionElement functionElement) { | 891 HGraph buildMethod(FunctionElement functionElement) { |
| 886 FunctionExpression function = functionElement.parseNode(compiler); | 892 FunctionExpression function = functionElement.parseNode(compiler); |
| 887 openFunction(functionElement, function); | 893 openFunction(functionElement, function); |
| 888 function.body.accept(this); | 894 function.body.accept(this); |
| 889 return closeFunction(); | 895 return closeFunction(); |
| 890 } | 896 } |
| 891 | 897 |
| 892 HGraph buildLazyInitializer(VariableElement variable) { | 898 HGraph buildLazyInitializer(VariableElement variable) { |
| 893 HBasicBlock block = graph.addNewBlock(); | |
| 894 open(graph.entry); | |
| 895 close(new HGoto()).addSuccessor(block); | |
| 896 open(block); | |
| 897 SendSet node = variable.parseNode(compiler); | 899 SendSet node = variable.parseNode(compiler); |
| 900 openFunction(variable, node); | |
| 898 Link<Node> link = node.arguments; | 901 Link<Node> link = node.arguments; |
| 899 assert(!link.isEmpty() && link.tail.isEmpty()); | 902 assert(!link.isEmpty() && link.tail.isEmpty()); |
| 900 visit(link.head); | 903 visit(link.head); |
| 901 close(new HReturn(pop())).addSuccessor(graph.exit); | 904 close(new HReturn(pop())).addSuccessor(graph.exit); |
| 902 graph.finalize(); | 905 return closeFunction(); |
| 903 return graph; | |
| 904 } | 906 } |
| 905 | 907 |
| 906 /** | 908 /** |
| 907 * Returns the constructor body associated with the given constructor or | 909 * Returns the constructor body associated with the given constructor or |
| 908 * creates a new constructor body, if none can be found. | 910 * creates a new constructor body, if none can be found. |
| 909 * | 911 * |
| 910 * Returns [:null:] if the constructor does not have a body. | 912 * Returns [:null:] if the constructor does not have a body. |
| 911 */ | 913 */ |
| 912 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { | 914 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { |
| 913 assert(constructor.isGenerativeConstructor()); | 915 assert(constructor.isGenerativeConstructor()); |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1306 | 1308 |
| 1307 // Create the instruction that parameter checks will use. | 1309 // Create the instruction that parameter checks will use. |
| 1308 check = new HNot(check); | 1310 check = new HNot(check); |
| 1309 add(check); | 1311 add(check); |
| 1310 | 1312 |
| 1311 ClosureClassMap closureData = localsHandler.closureData; | 1313 ClosureClassMap closureData = localsHandler.closureData; |
| 1312 Element checkResultElement = closureData.parametersWithSentinel[element]; | 1314 Element checkResultElement = closureData.parametersWithSentinel[element]; |
| 1313 localsHandler.updateLocal(checkResultElement, check); | 1315 localsHandler.updateLocal(checkResultElement, check); |
| 1314 } | 1316 } |
| 1315 | 1317 |
| 1316 void openFunction(FunctionElement functionElement, | 1318 void openFunction(Element element, Expression node) { |
| 1317 FunctionExpression node) { | |
| 1318 HBasicBlock block = graph.addNewBlock(); | 1319 HBasicBlock block = graph.addNewBlock(); |
| 1319 open(graph.entry); | 1320 open(graph.entry); |
| 1320 | 1321 |
| 1321 localsHandler.startFunction(functionElement, node); | 1322 localsHandler.startFunction(element, node); |
| 1322 close(new HGoto()).addSuccessor(block); | 1323 close(new HGoto()).addSuccessor(block); |
| 1323 | 1324 |
| 1324 open(block); | 1325 open(block); |
| 1325 | 1326 |
| 1326 FunctionSignature params = functionElement.computeSignature(compiler); | 1327 if (element is FunctionElement) { |
| 1327 params.forEachParameter((Element element) { | 1328 FunctionElement functionElement = element; |
| 1328 if (elements.isParameterChecked(element)) { | 1329 FunctionSignature params = functionElement.computeSignature(compiler); |
| 1329 addParameterCheckInstruction(element); | 1330 params.forEachParameter((Element parameterElement) { |
| 1330 } | 1331 if (elements.isParameterChecked(parameterElement)) { |
| 1331 }); | 1332 addParameterCheckInstruction(parameterElement); |
| 1333 } | |
| 1334 }); | |
| 1332 | 1335 |
| 1333 // Put the type checks in the first successor of the entry, | 1336 // Put the type checks in the first successor of the entry, |
| 1334 // because that is where the type guards will also be inserted. | 1337 // because that is where the type guards will also be inserted. |
| 1335 // This way we ensure that a type guard will dominate the type | 1338 // This way we ensure that a type guard will dominate the type |
| 1336 // check. | 1339 // check. |
| 1337 params.forEachParameter((Element element) { | 1340 params.forEachParameter((Element element) { |
| 1338 HInstruction newParameter = potentiallyCheckType( | 1341 HInstruction newParameter = potentiallyCheckType( |
| 1339 localsHandler.directLocals[element], element); | 1342 localsHandler.directLocals[element], element); |
| 1340 localsHandler.directLocals[element] = newParameter; | 1343 localsHandler.directLocals[element] = newParameter; |
| 1341 }); | 1344 }); |
| 1345 } else { | |
| 1346 // Otherwise it is a lazy initializer which does not have parameters. | |
| 1347 assert(element is VariableElement); | |
| 1348 } | |
| 1342 | 1349 |
| 1343 // Add the type parameters of the class as parameters of this | 1350 // Add the type parameters of the class as parameters of this |
| 1344 // method. | 1351 // method. |
| 1345 if (functionElement.isFactoryConstructor() | 1352 if (element.isFactoryConstructor() |
| 1346 || functionElement.isGenerativeConstructor()) { | 1353 || element.isGenerativeConstructor()) { |
| 1347 ClassElement cls = functionElement.enclosingElement; | 1354 ClassElement cls = element.enclosingElement; |
| 1348 cls.typeVariables.forEach((TypeVariableType typeVariable) { | 1355 cls.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1349 HParameterValue param = new HParameterValue(typeVariable.element); | 1356 HParameterValue param = new HParameterValue(typeVariable.element); |
| 1350 add(param); | 1357 add(param); |
| 1351 localsHandler.directLocals[typeVariable.element] = param; | 1358 localsHandler.directLocals[typeVariable.element] = param; |
| 1352 }); | 1359 }); |
| 1353 } | 1360 } |
| 1354 } | 1361 } |
| 1355 | 1362 |
| 1356 HInstruction potentiallyCheckType(HInstruction original, | 1363 HInstruction potentiallyCheckType(HInstruction original, |
| 1357 Element sourceElement) { | 1364 Element sourceElement) { |
| (...skipping 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2710 Element helper = interceptors.getThrowRuntimeError(); | 2717 Element helper = interceptors.getThrowRuntimeError(); |
| 2711 pushInvokeHelper1(helper, errorMessage); | 2718 pushInvokeHelper1(helper, errorMessage); |
| 2712 } | 2719 } |
| 2713 | 2720 |
| 2714 void generateThrowNoSuchMethod(Node diagnosticNode, | 2721 void generateThrowNoSuchMethod(Node diagnosticNode, |
| 2715 String methodName, | 2722 String methodName, |
| 2716 [Link<Node> argumentNodes, | 2723 [Link<Node> argumentNodes, |
| 2717 List<HInstruction> argumentValues]) { | 2724 List<HInstruction> argumentValues]) { |
| 2718 Element helper = | 2725 Element helper = |
| 2719 compiler.findHelper(const SourceString('throwNoSuchMethod')); | 2726 compiler.findHelper(const SourceString('throwNoSuchMethod')); |
| 2720 Constant receiverConstant = | 2727 Constant receiverConstant = |
| 2721 constantSystem.createString(new DartString.empty(), diagnosticNode); | 2728 constantSystem.createString(new DartString.empty(), diagnosticNode); |
| 2722 HInstruction receiver = graph.addConstant(receiverConstant); | 2729 HInstruction receiver = graph.addConstant(receiverConstant); |
| 2723 DartString dartString = new DartString.literal(methodName); | 2730 DartString dartString = new DartString.literal(methodName); |
| 2724 Constant nameConstant = | 2731 Constant nameConstant = |
| 2725 constantSystem.createString(dartString, diagnosticNode); | 2732 constantSystem.createString(dartString, diagnosticNode); |
| 2726 HInstruction name = graph.addConstant(nameConstant); | 2733 HInstruction name = graph.addConstant(nameConstant); |
| 2727 if (argumentValues == null) { | 2734 if (argumentValues == null) { |
| 2728 argumentValues = <HInstruction>[]; | 2735 argumentValues = <HInstruction>[]; |
| 2729 argumentNodes.forEach((argumentNode) { | 2736 argumentNodes.forEach((argumentNode) { |
| 2730 visit(argumentNode); | 2737 visit(argumentNode); |
| (...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4072 new HSubGraphBlockInformation(elseBranch.graph)); | 4079 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4073 | 4080 |
| 4074 HBasicBlock conditionStartBlock = conditionBranch.block; | 4081 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4075 conditionStartBlock.setBlockFlow(info, joinBlock); | 4082 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4076 SubGraph conditionGraph = conditionBranch.graph; | 4083 SubGraph conditionGraph = conditionBranch.graph; |
| 4077 HIf branch = conditionGraph.end.last; | 4084 HIf branch = conditionGraph.end.last; |
| 4078 assert(branch is HIf); | 4085 assert(branch is HIf); |
| 4079 branch.blockInformation = conditionStartBlock.blockFlow; | 4086 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4080 } | 4087 } |
| 4081 } | 4088 } |
| OLD | NEW |