| 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 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 updateLocal(boxedVariable, oldValue); | 360 updateLocal(boxedVariable, oldValue); |
| 361 } | 361 } |
| 362 updateLocal(boxElement, newBox); | 362 updateLocal(boxElement, newBox); |
| 363 } | 363 } |
| 364 | 364 |
| 365 /** | 365 /** |
| 366 * Documentation wanted -- johnniwinther | 366 * Documentation wanted -- johnniwinther |
| 367 * | 367 * |
| 368 * Invariant: [function] must be an implementation element. | 368 * Invariant: [function] must be an implementation element. |
| 369 */ | 369 */ |
| 370 void startFunction(FunctionElement function, | 370 void startFunction(Element element, Expression node) { |
| 371 FunctionExpression node) { | 371 assert(invariant(node, element.isImplementation)); |
| 372 assert(invariant(node, function.isImplementation)); | |
| 373 Compiler compiler = builder.compiler; | 372 Compiler compiler = builder.compiler; |
| 374 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( | 373 closureData = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 375 node, builder.elements); | 374 element, node, builder.elements); |
| 376 FunctionSignature signature = function.computeSignature(compiler); | 375 |
| 377 signature.orderedForEachParameter((Element element) { | 376 if (element is FunctionElement) { |
| 378 HInstruction parameter = new HParameterValue(element); | 377 FunctionElement functionElement = element; |
| 379 builder.add(parameter); | 378 FunctionSignature params = functionElement.computeSignature(compiler); |
| 380 builder.parameters[element] = parameter; | 379 params.orderedForEachParameter((Element parameterElement) { |
| 381 directLocals[element] = parameter; | 380 HInstruction parameter = new HParameterValue(parameterElement); |
| 382 parameter.guaranteedType = | 381 builder.add(parameter); |
| 383 builder.mapInferredType(typesTask.getGuaranteedTypeOfElement(element)); | 382 builder.parameters[parameterElement] = parameter; |
| 384 }); | 383 directLocals[parameterElement] = parameter; |
| 384 parameter.guaranteedType = |
| 385 builder.mapInferredType( |
| 386 typesTask.getGuaranteedTypeOfElement(parameterElement)); |
| 387 }); |
| 388 } |
| 385 | 389 |
| 386 enterScope(node); | 390 enterScope(node); |
| 387 | 391 |
| 388 // If the freeVariableMapping is not empty, then this function was a | 392 // If the freeVariableMapping is not empty, then this function was a |
| 389 // nested closure that captures variables. Redirect the captured | 393 // nested closure that captures variables. Redirect the captured |
| 390 // variables to fields in the closure. | 394 // variables to fields in the closure. |
| 391 closureData.freeVariableMapping.forEach((Element from, Element to) { | 395 closureData.freeVariableMapping.forEach((Element from, Element to) { |
| 392 redirectElement(from, to); | 396 redirectElement(from, to); |
| 393 }); | 397 }); |
| 394 if (closureData.isClosure()) { | 398 if (closureData.isClosure()) { |
| 395 // Inside closure redirect references to itself to [:this:]. | 399 // Inside closure redirect references to itself to [:this:]. |
| 396 HInstruction thisInstruction = new HThis(); | 400 HInstruction thisInstruction = new HThis(); |
| 397 builder.add(thisInstruction); | 401 builder.add(thisInstruction); |
| 398 updateLocal(closureData.closureElement, thisInstruction); | 402 updateLocal(closureData.closureElement, thisInstruction); |
| 399 } else if (function.isInstanceMember() | 403 } else if (element.isInstanceMember() |
| 400 || function.isGenerativeConstructor()) { | 404 || element.isGenerativeConstructor()) { |
| 401 // Once closures have been mapped to classes their instance members might | 405 // Once closures have been mapped to classes their instance members might |
| 402 // not have any thisElement if the closure was created inside a static | 406 // not have any thisElement if the closure was created inside a static |
| 403 // context. | 407 // context. |
| 404 ClassElement cls = function.getEnclosingClass(); | 408 ClassElement cls = element.getEnclosingClass(); |
| 405 DartType type = cls.computeType(builder.compiler); | 409 DartType type = cls.computeType(builder.compiler); |
| 406 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); | 410 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); |
| 407 builder.add(thisInstruction); | 411 builder.add(thisInstruction); |
| 408 directLocals[closureData.thisElement] = thisInstruction; | 412 directLocals[closureData.thisElement] = thisInstruction; |
| 409 } | 413 } |
| 410 } | 414 } |
| 411 | 415 |
| 412 bool hasValueForDirectLocal(Element element) { | 416 bool hasValueForDirectLocal(Element element) { |
| 413 assert(element !== null); | 417 assert(element !== null); |
| 414 assert(isAccessedDirectly(element)); | 418 assert(isAccessedDirectly(element)); |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 FunctionExpression function = functionElement.parseNode(compiler); | 927 FunctionExpression function = functionElement.parseNode(compiler); |
| 924 assert(function !== null); | 928 assert(function !== null); |
| 925 assert(!function.modifiers.isExternal()); | 929 assert(!function.modifiers.isExternal()); |
| 926 assert(elements[function] !== null); | 930 assert(elements[function] !== null); |
| 927 openFunction(functionElement, function); | 931 openFunction(functionElement, function); |
| 928 function.body.accept(this); | 932 function.body.accept(this); |
| 929 return closeFunction(); | 933 return closeFunction(); |
| 930 } | 934 } |
| 931 | 935 |
| 932 HGraph buildLazyInitializer(VariableElement variable) { | 936 HGraph buildLazyInitializer(VariableElement variable) { |
| 933 HBasicBlock block = graph.addNewBlock(); | |
| 934 open(graph.entry); | |
| 935 close(new HGoto()).addSuccessor(block); | |
| 936 open(block); | |
| 937 SendSet node = variable.parseNode(compiler); | 937 SendSet node = variable.parseNode(compiler); |
| 938 openFunction(variable, node); |
| 938 Link<Node> link = node.arguments; | 939 Link<Node> link = node.arguments; |
| 939 assert(!link.isEmpty() && link.tail.isEmpty()); | 940 assert(!link.isEmpty() && link.tail.isEmpty()); |
| 940 visit(link.head); | 941 visit(link.head); |
| 941 HInstruction value = pop(); | 942 HInstruction value = pop(); |
| 942 value = potentiallyCheckType(value, variable); | 943 value = potentiallyCheckType(value, variable); |
| 943 close(new HReturn(value)).addSuccessor(graph.exit); | 944 close(new HReturn(value)).addSuccessor(graph.exit); |
| 944 graph.finalize(); | 945 return closeFunction(); |
| 945 return graph; | |
| 946 } | 946 } |
| 947 | 947 |
| 948 /** | 948 /** |
| 949 * Returns the constructor body associated with the given constructor or | 949 * Returns the constructor body associated with the given constructor or |
| 950 * creates a new constructor body, if none can be found. | 950 * creates a new constructor body, if none can be found. |
| 951 * | 951 * |
| 952 * Returns [:null:] if the constructor does not have a body. | 952 * Returns [:null:] if the constructor does not have a body. |
| 953 */ | 953 */ |
| 954 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { | 954 ConstructorBodyElement getConstructorBody(FunctionElement constructor) { |
| 955 assert(constructor.isGenerativeConstructor()); | 955 assert(constructor.isGenerativeConstructor()); |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1404 ClosureClassMap closureData = localsHandler.closureData; | 1404 ClosureClassMap closureData = localsHandler.closureData; |
| 1405 Element checkResultElement = closureData.parametersWithSentinel[element]; | 1405 Element checkResultElement = closureData.parametersWithSentinel[element]; |
| 1406 localsHandler.updateLocal(checkResultElement, check); | 1406 localsHandler.updateLocal(checkResultElement, check); |
| 1407 } | 1407 } |
| 1408 | 1408 |
| 1409 /** | 1409 /** |
| 1410 * Documentation wanted -- johnniwinther | 1410 * Documentation wanted -- johnniwinther |
| 1411 * | 1411 * |
| 1412 * Invariant: [functionElement] must be the implementation element. | 1412 * Invariant: [functionElement] must be the implementation element. |
| 1413 */ | 1413 */ |
| 1414 void openFunction(FunctionElement functionElement, | 1414 void openFunction(Element element, Expression node) { |
| 1415 FunctionExpression node) { | 1415 assert(invariant(element, element.isImplementation)); |
| 1416 assert(invariant(functionElement, functionElement.isImplementation)); | |
| 1417 HBasicBlock block = graph.addNewBlock(); | 1416 HBasicBlock block = graph.addNewBlock(); |
| 1418 open(graph.entry); | 1417 open(graph.entry); |
| 1419 | 1418 |
| 1420 localsHandler.startFunction(functionElement, node); | 1419 localsHandler.startFunction(element, node); |
| 1421 close(new HGoto()).addSuccessor(block); | 1420 close(new HGoto()).addSuccessor(block); |
| 1422 | 1421 |
| 1423 open(block); | 1422 open(block); |
| 1424 | 1423 |
| 1425 FunctionSignature params = functionElement.computeSignature(compiler); | 1424 if (element is FunctionElement) { |
| 1426 params.orderedForEachParameter((Element element) { | 1425 FunctionElement functionElement = element; |
| 1427 if (elements.isParameterChecked(element)) { | 1426 FunctionSignature params = functionElement.computeSignature(compiler); |
| 1428 addParameterCheckInstruction(element); | 1427 params.orderedForEachParameter((Element parameterElement) { |
| 1429 } | 1428 if (elements.isParameterChecked(parameterElement)) { |
| 1430 }); | 1429 addParameterCheckInstruction(parameterElement); |
| 1430 } |
| 1431 }); |
| 1431 | 1432 |
| 1432 // Put the type checks in the first successor of the entry, | 1433 // Put the type checks in the first successor of the entry, |
| 1433 // because that is where the type guards will also be inserted. | 1434 // because that is where the type guards will also be inserted. |
| 1434 // This way we ensure that a type guard will dominate the type | 1435 // This way we ensure that a type guard will dominate the type |
| 1435 // check. | 1436 // check. |
| 1436 params.orderedForEachParameter((Element element) { | 1437 params.orderedForEachParameter((Element element) { |
| 1437 HInstruction newParameter = potentiallyCheckType( | 1438 HInstruction newParameter = potentiallyCheckType( |
| 1438 localsHandler.directLocals[element], element); | 1439 localsHandler.directLocals[element], element); |
| 1439 localsHandler.directLocals[element] = newParameter; | 1440 localsHandler.directLocals[element] = newParameter; |
| 1440 }); | 1441 }); |
| 1442 } else { |
| 1443 // Otherwise it is a lazy initializer which does not have parameters. |
| 1444 assert(element is VariableElement); |
| 1445 } |
| 1441 | 1446 |
| 1442 // Add the type parameters of the class as parameters of this | 1447 // Add the type parameters of the class as parameters of this |
| 1443 // method. | 1448 // method. |
| 1444 var enclosing = functionElement.enclosingElement; | 1449 var enclosing = element.enclosingElement; |
| 1445 if (functionElement.isConstructor() && compiler.world.needsRti(enclosing)) { | 1450 if (element.isConstructor() && compiler.world.needsRti(enclosing)) { |
| 1446 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { | 1451 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { |
| 1447 HParameterValue param = new HParameterValue(typeVariable.element); | 1452 HParameterValue param = new HParameterValue(typeVariable.element); |
| 1448 add(param); | 1453 add(param); |
| 1449 localsHandler.directLocals[typeVariable.element] = param; | 1454 localsHandler.directLocals[typeVariable.element] = param; |
| 1450 }); | 1455 }); |
| 1451 } | 1456 } |
| 1452 } | 1457 } |
| 1453 | 1458 |
| 1454 HInstruction potentiallyCheckType( | 1459 HInstruction potentiallyCheckType( |
| 1455 HInstruction original, Element sourceElement, | 1460 HInstruction original, Element sourceElement, |
| (...skipping 2998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4454 new HSubGraphBlockInformation(elseBranch.graph)); | 4459 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4455 | 4460 |
| 4456 HBasicBlock conditionStartBlock = conditionBranch.block; | 4461 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4457 conditionStartBlock.setBlockFlow(info, joinBlock); | 4462 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4458 SubGraph conditionGraph = conditionBranch.graph; | 4463 SubGraph conditionGraph = conditionBranch.graph; |
| 4459 HIf branch = conditionGraph.end.last; | 4464 HIf branch = conditionGraph.end.last; |
| 4460 assert(branch is HIf); | 4465 assert(branch is HIf); |
| 4461 branch.blockInformation = conditionStartBlock.blockFlow; | 4466 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4462 } | 4467 } |
| 4463 } | 4468 } |
| OLD | NEW |