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 import 'dart:collection'; | 5 import 'dart:collection'; |
6 | 6 |
7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
8 | 8 |
9 import '../closure.dart'; | 9 import '../closure.dart'; |
10 import '../common.dart'; | 10 import '../common.dart'; |
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 | 1004 |
1005 // Build the initializers in the context of the new constructor. | 1005 // Build the initializers in the context of the new constructor. |
1006 ResolvedAst oldResolvedAst = resolvedAst; | 1006 ResolvedAst oldResolvedAst = resolvedAst; |
1007 resolvedAst = callee.resolvedAst; | 1007 resolvedAst = callee.resolvedAst; |
1008 final oldElementInferenceResults = elementInferenceResults; | 1008 final oldElementInferenceResults = elementInferenceResults; |
1009 elementInferenceResults = globalInferenceResults.resultOfMember(callee); | 1009 elementInferenceResults = globalInferenceResults.resultOfMember(callee); |
1010 ScopeInfo oldScopeInfo = localsHandler.scopeInfo; | 1010 ScopeInfo oldScopeInfo = localsHandler.scopeInfo; |
1011 ScopeInfo newScopeInfo = closureDataLookup.getScopeInfo(callee); | 1011 ScopeInfo newScopeInfo = closureDataLookup.getScopeInfo(callee); |
1012 localsHandler.scopeInfo = newScopeInfo; | 1012 localsHandler.scopeInfo = newScopeInfo; |
1013 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 1013 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
1014 localsHandler.enterScope(closureDataLookup.getClosureScope(callee), | 1014 localsHandler.enterScope(closureDataLookup.getScopeInClosure(callee), |
1015 forGenerativeConstructorBody: callee.isGenerativeConstructorBody); | 1015 forGenerativeConstructorBody: callee.isGenerativeConstructorBody); |
1016 } | 1016 } |
1017 buildInitializers(callee, constructorResolvedAsts, fieldValues); | 1017 buildInitializers(callee, constructorResolvedAsts, fieldValues); |
1018 localsHandler.scopeInfo = oldScopeInfo; | 1018 localsHandler.scopeInfo = oldScopeInfo; |
1019 resolvedAst = oldResolvedAst; | 1019 resolvedAst = oldResolvedAst; |
1020 elementInferenceResults = oldElementInferenceResults; | 1020 elementInferenceResults = oldElementInferenceResults; |
1021 }); | 1021 }); |
1022 } | 1022 } |
1023 | 1023 |
1024 void buildInitializers( | 1024 void buildInitializers( |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 // If [parameter] is boxed, it will be a field in the box passed as the | 1359 // If [parameter] is boxed, it will be a field in the box passed as the |
1360 // last parameter. So no need to directly pass it. | 1360 // last parameter. So no need to directly pass it. |
1361 if (!localsHandler.isBoxed(parameter)) { | 1361 if (!localsHandler.isBoxed(parameter)) { |
1362 bodyCallInputs.add(localsHandler.readLocal(parameter)); | 1362 bodyCallInputs.add(localsHandler.readLocal(parameter)); |
1363 } | 1363 } |
1364 }); | 1364 }); |
1365 | 1365 |
1366 // If there are locals that escape (ie mutated in closures), we | 1366 // If there are locals that escape (ie mutated in closures), we |
1367 // pass the box to the constructor. | 1367 // pass the box to the constructor. |
1368 // The box must be passed before any type variable. | 1368 // The box must be passed before any type variable. |
1369 ClosureScope scopeData = closureDataLookup.getClosureScope(constructor); | 1369 ScopeInClosure scopeData = |
| 1370 closureDataLookup.getScopeInClosure(constructor); |
1370 if (scopeData.requiresContextBox) { | 1371 if (scopeData.requiresContextBox) { |
1371 bodyCallInputs.add(localsHandler.readLocal(scopeData.context)); | 1372 bodyCallInputs.add(localsHandler.readLocal(scopeData.context)); |
1372 } | 1373 } |
1373 | 1374 |
1374 // Type variables arguments must come after the box (if there is one). | 1375 // Type variables arguments must come after the box (if there is one). |
1375 ClassElement currentClass = constructor.enclosingClass; | 1376 ClassElement currentClass = constructor.enclosingClass; |
1376 if (rtiNeed.classNeedsRti(currentClass)) { | 1377 if (rtiNeed.classNeedsRti(currentClass)) { |
1377 // If [currentClass] needs RTI, we add the type variables as | 1378 // If [currentClass] needs RTI, we add the type variables as |
1378 // parameters of the generative constructor body. | 1379 // parameters of the generative constructor body. |
1379 currentClass.typeVariables.forEach((_argument) { | 1380 currentClass.typeVariables.forEach((_argument) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1420 element.functionSignature.orderedForEachParameter((_parameter) { | 1421 element.functionSignature.orderedForEachParameter((_parameter) { |
1421 ParameterElement parameter = _parameter; | 1422 ParameterElement parameter = _parameter; |
1422 parameters[parameter] = TypeMaskFactory.inferredTypeForParameter( | 1423 parameters[parameter] = TypeMaskFactory.inferredTypeForParameter( |
1423 parameter, globalInferenceResults); | 1424 parameter, globalInferenceResults); |
1424 }); | 1425 }); |
1425 } | 1426 } |
1426 | 1427 |
1427 localsHandler.startFunction( | 1428 localsHandler.startFunction( |
1428 element, | 1429 element, |
1429 closureDataLookup.getScopeInfo(element), | 1430 closureDataLookup.getScopeInfo(element), |
1430 closureDataLookup.getClosureScope(element), | 1431 closureDataLookup.getScopeInClosure(element), |
1431 parameters, | 1432 parameters, |
1432 isGenerativeConstructorBody: element.isGenerativeConstructorBody); | 1433 isGenerativeConstructorBody: element.isGenerativeConstructorBody); |
1433 close(new HGoto()).addSuccessor(block); | 1434 close(new HGoto()).addSuccessor(block); |
1434 | 1435 |
1435 open(block); | 1436 open(block); |
1436 | 1437 |
1437 // Add the type parameters of the class as parameters of this method. This | 1438 // Add the type parameters of the class as parameters of this method. This |
1438 // must be done before adding the normal parameters, because their types | 1439 // must be done before adding the normal parameters, because their types |
1439 // may contain references to type variables. | 1440 // may contain references to type variables. |
1440 ClassElement cls = element.enclosingClass; | 1441 ClassElement cls = element.enclosingClass; |
(...skipping 13 matching lines...) Expand all Loading... |
1454 FunctionSignature signature = functionElement.functionSignature; | 1455 FunctionSignature signature = functionElement.functionSignature; |
1455 | 1456 |
1456 // Put the type checks in the first successor of the entry, | 1457 // Put the type checks in the first successor of the entry, |
1457 // because that is where the type guards will also be inserted. | 1458 // because that is where the type guards will also be inserted. |
1458 // This way we ensure that a type guard will dominate the type | 1459 // This way we ensure that a type guard will dominate the type |
1459 // check. | 1460 // check. |
1460 signature.orderedForEachParameter((_parameterElement) { | 1461 signature.orderedForEachParameter((_parameterElement) { |
1461 ParameterElement parameterElement = _parameterElement; | 1462 ParameterElement parameterElement = _parameterElement; |
1462 if (element.isGenerativeConstructorBody) { | 1463 if (element.isGenerativeConstructorBody) { |
1463 if (closureDataLookup | 1464 if (closureDataLookup |
1464 .getClosureScope(element) | 1465 .getScopeInClosure(element) |
1465 .isBoxed(parameterElement)) { | 1466 .isBoxed(parameterElement)) { |
1466 // The parameter will be a field in the box passed as the | 1467 // The parameter will be a field in the box passed as the |
1467 // last parameter. So no need to have it. | 1468 // last parameter. So no need to have it. |
1468 return; | 1469 return; |
1469 } | 1470 } |
1470 } | 1471 } |
1471 HInstruction newParameter = | 1472 HInstruction newParameter = |
1472 localsHandler.directLocals[parameterElement]; | 1473 localsHandler.directLocals[parameterElement]; |
1473 if (!element.isConstructor || | 1474 if (!element.isConstructor || |
1474 !(element as ConstructorElement).isRedirectingFactory) { | 1475 !(element as ConstructorElement).isRedirectingFactory) { |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1698 pop(); | 1699 pop(); |
1699 } | 1700 } |
1700 } | 1701 } |
1701 | 1702 |
1702 void buildBody() { | 1703 void buildBody() { |
1703 visit(node.body); | 1704 visit(node.body); |
1704 } | 1705 } |
1705 | 1706 |
1706 loopHandler.handleLoop( | 1707 loopHandler.handleLoop( |
1707 node, | 1708 node, |
1708 closureDataLookup.getLoopClosureScope(node), | 1709 closureDataLookup.getLoopScopeInClosure(node), |
1709 elements.getTargetDefinition(node), | 1710 elements.getTargetDefinition(node), |
1710 buildInitializer, | 1711 buildInitializer, |
1711 buildCondition, | 1712 buildCondition, |
1712 buildUpdate, | 1713 buildUpdate, |
1713 buildBody); | 1714 buildBody); |
1714 } | 1715 } |
1715 | 1716 |
1716 visitWhile(ast.While node) { | 1717 visitWhile(ast.While node) { |
1717 assert(isReachable); | 1718 assert(isReachable); |
1718 HInstruction buildCondition() { | 1719 HInstruction buildCondition() { |
1719 visit(node.condition); | 1720 visit(node.condition); |
1720 return popBoolified(); | 1721 return popBoolified(); |
1721 } | 1722 } |
1722 | 1723 |
1723 loopHandler.handleLoop(node, closureDataLookup.getLoopClosureScope(node), | 1724 loopHandler.handleLoop(node, closureDataLookup.getLoopScopeInClosure(node), |
1724 elements.getTargetDefinition(node), () {}, buildCondition, () {}, () { | 1725 elements.getTargetDefinition(node), () {}, buildCondition, () {}, () { |
1725 visit(node.body); | 1726 visit(node.body); |
1726 }); | 1727 }); |
1727 } | 1728 } |
1728 | 1729 |
1729 visitDoWhile(ast.DoWhile node) { | 1730 visitDoWhile(ast.DoWhile node) { |
1730 assert(isReachable); | 1731 assert(isReachable); |
1731 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); | 1732 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
1732 var loopClosureInfo = closureDataLookup.getLoopClosureScope(node); | 1733 var loopClosureInfo = closureDataLookup.getLoopScopeInClosure(node); |
1733 localsHandler.startLoop(loopClosureInfo); | 1734 localsHandler.startLoop(loopClosureInfo); |
1734 loopDepth++; | 1735 loopDepth++; |
1735 JumpTarget target = elements.getTargetDefinition(node); | 1736 JumpTarget target = elements.getTargetDefinition(node); |
1736 JumpHandler jumpHandler = loopHandler.beginLoopHeader(node, target); | 1737 JumpHandler jumpHandler = loopHandler.beginLoopHeader(node, target); |
1737 HLoopInformation loopInfo = current.loopInformation; | 1738 HLoopInformation loopInfo = current.loopInformation; |
1738 HBasicBlock loopEntryBlock = current; | 1739 HBasicBlock loopEntryBlock = current; |
1739 HBasicBlock bodyEntryBlock = current; | 1740 HBasicBlock bodyEntryBlock = current; |
1740 bool hasContinues = target != null && target.isContinueTarget; | 1741 bool hasContinues = target != null && target.isContinueTarget; |
1741 if (hasContinues) { | 1742 if (hasContinues) { |
1742 // Add extra block to hang labels on. | 1743 // Add extra block to hang labels on. |
(...skipping 3689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5432 pop(); // Pop the value pushed by the setter call. | 5433 pop(); // Pop the value pushed by the setter call. |
5433 | 5434 |
5434 visit(node.body); | 5435 visit(node.body); |
5435 } | 5436 } |
5436 | 5437 |
5437 void buildUpdate() {} | 5438 void buildUpdate() {} |
5438 | 5439 |
5439 buildProtectedByFinally(() { | 5440 buildProtectedByFinally(() { |
5440 loopHandler.handleLoop( | 5441 loopHandler.handleLoop( |
5441 node, | 5442 node, |
5442 closureDataLookup.getLoopClosureScope(node), | 5443 closureDataLookup.getLoopScopeInClosure(node), |
5443 elements.getTargetDefinition(node), | 5444 elements.getTargetDefinition(node), |
5444 buildInitializer, | 5445 buildInitializer, |
5445 buildCondition, | 5446 buildCondition, |
5446 buildUpdate, | 5447 buildUpdate, |
5447 buildBody); | 5448 buildBody); |
5448 }, () { | 5449 }, () { |
5449 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); | 5450 pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]); |
5450 push(new HAwait(pop(), | 5451 push(new HAwait(pop(), |
5451 new TypeMask.subclass(commonElements.objectClass, closedWorld))); | 5452 new TypeMask.subclass(commonElements.objectClass, closedWorld))); |
5452 pop(); | 5453 pop(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5505 void buildBody() { | 5506 void buildBody() { |
5506 Selector call = Selectors.current; | 5507 Selector call = Selectors.current; |
5507 TypeMask mask = elementInferenceResults.typeOfIteratorCurrent(node); | 5508 TypeMask mask = elementInferenceResults.typeOfIteratorCurrent(node); |
5508 pushInvokeDynamic(node, call, mask, [iterator]); | 5509 pushInvokeDynamic(node, call, mask, [iterator]); |
5509 buildAssignLoopVariable(node, pop()); | 5510 buildAssignLoopVariable(node, pop()); |
5510 visit(node.body); | 5511 visit(node.body); |
5511 } | 5512 } |
5512 | 5513 |
5513 loopHandler.handleLoop( | 5514 loopHandler.handleLoop( |
5514 node, | 5515 node, |
5515 closureDataLookup.getLoopClosureScope(node), | 5516 closureDataLookup.getLoopScopeInClosure(node), |
5516 elements.getTargetDefinition(node), | 5517 elements.getTargetDefinition(node), |
5517 buildInitializer, | 5518 buildInitializer, |
5518 buildCondition, | 5519 buildCondition, |
5519 () {}, | 5520 () {}, |
5520 buildBody); | 5521 buildBody); |
5521 } | 5522 } |
5522 | 5523 |
5523 buildAssignLoopVariable(ast.ForIn node, HInstruction value) { | 5524 buildAssignLoopVariable(ast.ForIn node, HInstruction value) { |
5524 ast.Node identifier = node.declaredIdentifier; | 5525 ast.Node identifier = node.declaredIdentifier; |
5525 Element variable = elements.getForInVariable(node); | 5526 Element variable = elements.getForInVariable(node); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5630 HInstruction index = localsHandler.readLocal(indexVariable); | 5631 HInstruction index = localsHandler.readLocal(indexVariable); |
5631 HInstruction one = graph.addConstantInt(1, closedWorld); | 5632 HInstruction one = graph.addConstantInt(1, closedWorld); |
5632 HInstruction addInstruction = | 5633 HInstruction addInstruction = |
5633 new HAdd(index, one, null, commonMasks.positiveIntType); | 5634 new HAdd(index, one, null, commonMasks.positiveIntType); |
5634 add(addInstruction); | 5635 add(addInstruction); |
5635 localsHandler.updateLocal(indexVariable, addInstruction); | 5636 localsHandler.updateLocal(indexVariable, addInstruction); |
5636 } | 5637 } |
5637 | 5638 |
5638 loopHandler.handleLoop( | 5639 loopHandler.handleLoop( |
5639 node, | 5640 node, |
5640 closureDataLookup.getLoopClosureScope(node), | 5641 closureDataLookup.getLoopScopeInClosure(node), |
5641 elements.getTargetDefinition(node), | 5642 elements.getTargetDefinition(node), |
5642 buildInitializer, | 5643 buildInitializer, |
5643 buildCondition, | 5644 buildCondition, |
5644 buildUpdate, | 5645 buildUpdate, |
5645 buildBody); | 5646 buildBody); |
5646 } | 5647 } |
5647 | 5648 |
5648 visitLabel(ast.Label node) { | 5649 visitLabel(ast.Label node) { |
5649 reporter.internalError(node, 'SsaFromAstMixin.visitLabel.'); | 5650 reporter.internalError(node, 'SsaFromAstMixin.visitLabel.'); |
5650 } | 5651 } |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5985 node, | 5986 node, |
5986 new NullJumpHandler(reporter), | 5987 new NullJumpHandler(reporter), |
5987 buildExpression, | 5988 buildExpression, |
5988 node.cases, | 5989 node.cases, |
5989 getConstants, | 5990 getConstants, |
5990 (_) => false, // No case is default. | 5991 (_) => false, // No case is default. |
5991 buildSwitchCase); | 5992 buildSwitchCase); |
5992 } | 5993 } |
5993 | 5994 |
5994 void buildLoop() { | 5995 void buildLoop() { |
5995 loopHandler.handleLoop(node, closureDataLookup.getLoopClosureScope(node), | 5996 loopHandler.handleLoop( |
5996 switchTarget, () {}, buildCondition, () {}, buildSwitch); | 5997 node, |
| 5998 closureDataLookup.getLoopScopeInClosure(node), |
| 5999 switchTarget, |
| 6000 () {}, |
| 6001 buildCondition, |
| 6002 () {}, |
| 6003 buildSwitch); |
5997 } | 6004 } |
5998 | 6005 |
5999 if (hasDefault) { | 6006 if (hasDefault) { |
6000 buildLoop(); | 6007 buildLoop(); |
6001 } else { | 6008 } else { |
6002 // If the switch statement has no default case, surround the loop with | 6009 // If the switch statement has no default case, surround the loop with |
6003 // a test of the target. | 6010 // a test of the target. |
6004 void buildCondition() { | 6011 void buildCondition() { |
6005 js.Template code = js.js.parseForeignJS('#'); | 6012 js.Template code = js.js.parseForeignJS('#'); |
6006 push(new HForeignCode( | 6013 push(new HForeignCode( |
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6843 this.oldReturnLocal, | 6850 this.oldReturnLocal, |
6844 this.oldReturnType, | 6851 this.oldReturnType, |
6845 this.oldResolvedAst, | 6852 this.oldResolvedAst, |
6846 this.oldStack, | 6853 this.oldStack, |
6847 this.oldLocalsHandler, | 6854 this.oldLocalsHandler, |
6848 this.inTryStatement, | 6855 this.inTryStatement, |
6849 this.allFunctionsCalledOnce, | 6856 this.allFunctionsCalledOnce, |
6850 this.oldElementInferenceResults) | 6857 this.oldElementInferenceResults) |
6851 : super(function); | 6858 : super(function); |
6852 } | 6859 } |
OLD | NEW |