Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../closure.dart'; | |
| 7 import '../common.dart'; | 8 import '../common.dart'; |
| 8 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 9 import '../common/names.dart'; | 10 import '../common/names.dart'; |
| 10 import '../common/tasks.dart' show CompilerTask; | 11 import '../common/tasks.dart' show CompilerTask; |
| 11 import '../compiler.dart'; | 12 import '../compiler.dart'; |
| 12 import '../constants/values.dart' | 13 import '../constants/values.dart' |
| 13 show | 14 show |
| 14 ConstantValue, | 15 ConstantValue, |
| 15 InterceptorConstantValue, | 16 InterceptorConstantValue, |
| 16 StringConstantValue, | 17 StringConstantValue, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 sourceInformationBuilder.buildVariableDeclaration(); | 108 sourceInformationBuilder.buildVariableDeclaration(); |
| 108 this.localsHandler = new LocalsHandler(this, targetElement, null, compiler); | 109 this.localsHandler = new LocalsHandler(this, targetElement, null, compiler); |
| 109 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend, | 110 this.astAdapter = new KernelAstAdapter(kernel, compiler.backend, |
| 110 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); | 111 resolvedAst, kernel.nodeToAst, kernel.nodeToElement); |
| 111 Element originTarget = targetElement; | 112 Element originTarget = targetElement; |
| 112 if (originTarget.isPatch) { | 113 if (originTarget.isPatch) { |
| 113 originTarget = originTarget.origin; | 114 originTarget = originTarget.origin; |
| 114 } | 115 } |
| 115 if (originTarget is FunctionElement) { | 116 if (originTarget is FunctionElement) { |
| 116 target = kernel.functions[originTarget]; | 117 target = kernel.functions[originTarget]; |
| 118 // Closures require a lookup one level deeper in the closure class mapper. | |
| 119 if (target == null) { | |
| 120 ClosureClassMap classMap = compiler.closureToClassMapper | |
| 121 .getClosureToClassMapping(originTarget.resolvedAst); | |
| 122 if (classMap.closureElement != null) { | |
| 123 target = kernel.localFunctions[classMap.closureElement]; | |
| 124 } | |
| 125 } | |
| 117 } else if (originTarget is FieldElement) { | 126 } else if (originTarget is FieldElement) { |
| 118 target = kernel.fields[originTarget]; | 127 target = kernel.fields[originTarget]; |
| 119 } | 128 } |
| 120 } | 129 } |
| 121 | 130 |
| 122 HGraph build() { | 131 HGraph build() { |
| 123 // TODO(het): no reason to do this here... | 132 // TODO(het): no reason to do this here... |
| 124 HInstruction.idCounter = 0; | 133 HInstruction.idCounter = 0; |
| 125 if (target is ir.Procedure) { | 134 if (target is ir.Procedure) { |
| 126 buildProcedure(target); | 135 buildProcedure(target); |
| 127 } else if (target is ir.Field) { | 136 } else if (target is ir.Field) { |
| 128 buildField(target); | 137 buildField(target); |
| 129 } else if (target is ir.Constructor) { | 138 } else if (target is ir.Constructor) { |
| 130 buildConstructor(target); | 139 buildConstructor(target); |
| 140 } else if (target is ir.FunctionExpression) { | |
| 141 buildFuncExpr(target); | |
| 142 } else { | |
| 143 throw 'No case implemented to handle $target'; | |
| 131 } | 144 } |
| 132 assert(graph.isValid()); | 145 assert(graph.isValid()); |
| 133 return graph; | 146 return graph; |
| 134 } | 147 } |
| 135 | 148 |
| 136 void buildField(ir.Field field) { | 149 void buildField(ir.Field field) { |
| 137 openFunction(); | 150 openFunction(); |
| 138 if (field.initializer != null) { | 151 if (field.initializer != null) { |
| 139 field.initializer.accept(this); | 152 field.initializer.accept(this); |
| 140 } else { | 153 } else { |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 334 type, kind, original.instructionType, reifiedType, original); | 347 type, kind, original.instructionType, reifiedType, original); |
| 335 } | 348 } |
| 336 | 349 |
| 337 /// Builds a SSA graph for [procedure]. | 350 /// Builds a SSA graph for [procedure]. |
| 338 void buildProcedure(ir.Procedure procedure) { | 351 void buildProcedure(ir.Procedure procedure) { |
| 339 openFunction(); | 352 openFunction(); |
| 340 procedure.function.body.accept(this); | 353 procedure.function.body.accept(this); |
| 341 closeFunction(); | 354 closeFunction(); |
| 342 } | 355 } |
| 343 | 356 |
| 357 // TODO(efortuna): This function is identical to the one above. Waiting for | |
| 358 // response from Asger and Kevin on if we should implement a common interface | |
| 359 // between Procedure and FunctionExpression. Regardless, this function is | |
| 360 // definitely not permanent. | |
| 361 void buildFuncExpr(ir.FunctionExpression procedure) { | |
| 362 openFunction(); | |
| 363 procedure.function.body.accept(this); | |
| 364 closeFunction(); | |
| 365 } | |
| 366 | |
| 344 void addImplicitInstantiation(DartType type) { | 367 void addImplicitInstantiation(DartType type) { |
| 345 if (type != null) { | 368 if (type != null) { |
| 346 currentImplicitInstantiations.add(type); | 369 currentImplicitInstantiations.add(type); |
| 347 } | 370 } |
| 348 } | 371 } |
| 349 | 372 |
| 350 void removeImplicitInstantiation(DartType type) { | 373 void removeImplicitInstantiation(DartType type) { |
| 351 if (type != null) { | 374 if (type != null) { |
| 352 currentImplicitInstantiations.removeLast(); | 375 currentImplicitInstantiations.removeLast(); |
| 353 } | 376 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 exprStatement.expression.accept(this); | 449 exprStatement.expression.accept(this); |
| 427 pop(); | 450 pop(); |
| 428 } | 451 } |
| 429 | 452 |
| 430 @override | 453 @override |
| 431 void visitReturnStatement(ir.ReturnStatement returnStatement) { | 454 void visitReturnStatement(ir.ReturnStatement returnStatement) { |
| 432 HInstruction value; | 455 HInstruction value; |
| 433 if (returnStatement.expression == null) { | 456 if (returnStatement.expression == null) { |
| 434 value = graph.addConstantNull(compiler); | 457 value = graph.addConstantNull(compiler); |
| 435 } else { | 458 } else { |
| 436 assert(target is ir.Procedure); | 459 assert(target is ir.Procedure || target is ir.FunctionExpression); |
| 437 returnStatement.expression.accept(this); | 460 returnStatement.expression.accept(this); |
| 461 // More stupidity until we resolve the interface issue with | |
| 462 // FunctionExpressions and Procedures. | |
|
sra1
2016/12/06 02:35:41
It might be possible to simply use ir.FunctionNode
Emily Fortuna
2016/12/06 18:49:22
Done.
| |
| 463 // TODO(efortuna): Remove! | |
| 464 ir.FunctionNode functionNode; | |
| 465 if (target is ir.Procedure) { | |
| 466 functionNode = (target as ir.Procedure).function; | |
| 467 } else if (target is ir.FunctionExpression) { | |
| 468 functionNode = (target as ir.FunctionExpression).function; | |
| 469 } | |
| 438 value = typeBuilder.potentiallyCheckOrTrustType(pop(), | 470 value = typeBuilder.potentiallyCheckOrTrustType(pop(), |
| 439 astAdapter.getFunctionReturnType((target as ir.Procedure).function)); | 471 astAdapter.getFunctionReturnType(functionNode)); |
| 440 } | 472 } |
| 441 // TODO(het): Add source information | 473 // TODO(het): Add source information |
| 442 // TODO(het): Set a return value instead of closing the function when we | 474 // TODO(het): Set a return value instead of closing the function when we |
| 443 // support inlining. | 475 // support inlining. |
| 444 closeAndGotoExit(new HReturn(value, null)); | 476 closeAndGotoExit(new HReturn(value, null)); |
| 445 } | 477 } |
| 446 | 478 |
| 447 @override | 479 @override |
| 448 void visitForStatement(ir.ForStatement forStatement) { | 480 void visitForStatement(ir.ForStatement forStatement) { |
| 449 assert(isReachable); | 481 assert(isReachable); |
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1312 if (_unexpectedForeignArguments(invocation, 1, 1)) { | 1344 if (_unexpectedForeignArguments(invocation, 1, 1)) { |
| 1313 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | 1345 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. |
| 1314 return; | 1346 return; |
| 1315 } | 1347 } |
| 1316 | 1348 |
| 1317 List<HInstruction> inputs = _visitArguments(invocation.arguments); | 1349 List<HInstruction> inputs = _visitArguments(invocation.arguments); |
| 1318 | 1350 |
| 1319 String isolateName = backend.namer.staticStateHolder; | 1351 String isolateName = backend.namer.staticStateHolder; |
| 1320 SideEffects sideEffects = new SideEffects.empty(); | 1352 SideEffects sideEffects = new SideEffects.empty(); |
| 1321 sideEffects.setAllSideEffects(); | 1353 sideEffects.setAllSideEffects(); |
| 1322 push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"), | 1354 push(new HForeignCode( |
| 1323 backend.dynamicType, inputs, | 1355 js.js.parseForeignJS("$isolateName = #"), backend.dynamicType, inputs, |
| 1324 nativeBehavior: native.NativeBehavior.CHANGES_OTHER, | 1356 nativeBehavior: native.NativeBehavior.CHANGES_OTHER, |
| 1325 effects: sideEffects)); | 1357 effects: sideEffects)); |
| 1326 } | 1358 } |
| 1327 | 1359 |
| 1328 void handleForeignJsGetStaticState(ir.StaticInvocation invocation) { | 1360 void handleForeignJsGetStaticState(ir.StaticInvocation invocation) { |
| 1329 if (_unexpectedForeignArguments(invocation, 0, 0)) { | 1361 if (_unexpectedForeignArguments(invocation, 0, 0)) { |
| 1330 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. | 1362 stack.add(graph.addConstantNull(compiler)); // Result expected on stack. |
| 1331 return; | 1363 return; |
| 1332 } | 1364 } |
| 1333 | 1365 |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1555 if (selector.isGetter) { | 1587 if (selector.isGetter) { |
| 1556 push(new HInvokeDynamicGetter(selector, mask, null, inputs, type)); | 1588 push(new HInvokeDynamicGetter(selector, mask, null, inputs, type)); |
| 1557 } else if (selector.isSetter) { | 1589 } else if (selector.isSetter) { |
| 1558 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)); | 1590 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)); |
| 1559 } else { | 1591 } else { |
| 1560 push(new HInvokeDynamicMethod( | 1592 push(new HInvokeDynamicMethod( |
| 1561 selector, mask, inputs, type, isIntercepted)); | 1593 selector, mask, inputs, type, isIntercepted)); |
| 1562 } | 1594 } |
| 1563 } | 1595 } |
| 1564 | 1596 |
| 1597 @override | |
| 1598 void visitFunctionExpression(ir.FunctionExpression funcExpression) { | |
| 1599 LocalFunctionElement methodElement = astAdapter.getElement(funcExpression); | |
| 1600 ClosureClassMap nestedClosureData = compiler.closureToClassMapper | |
| 1601 .getClosureToClassMapping(methodElement.resolvedAst); | |
| 1602 assert(nestedClosureData != null); | |
| 1603 assert(nestedClosureData.closureClassElement != null); | |
| 1604 ClosureClassElement closureClassElement = | |
| 1605 nestedClosureData.closureClassElement; | |
| 1606 FunctionElement callElement = nestedClosureData.callElement; | |
| 1607 // TODO(ahe): This should be registered in codegen, not here. | |
| 1608 // TODO(johnniwinther): Is [registerStaticUse] equivalent to | |
| 1609 // [addToWorkList]? | |
| 1610 registry?.registerStaticUse(new StaticUse.foreignUse(callElement)); | |
|
Harry Terkelsen
2016/12/06 18:46:36
johnni is making some changes to the registry. I w
Emily Fortuna
2016/12/06 18:49:22
Acknowledged.
| |
| 1611 | |
| 1612 List<HInstruction> capturedVariables = <HInstruction>[]; | |
| 1613 closureClassElement.closureFields.forEach((ClosureFieldElement field) { | |
| 1614 Local capturedLocal = | |
| 1615 nestedClosureData.getLocalVariableForClosureField(field); | |
| 1616 assert(capturedLocal != null); | |
| 1617 capturedVariables.add(localsHandler.readLocal(capturedLocal)); | |
| 1618 }); | |
| 1619 | |
| 1620 TypeMask type = | |
| 1621 new TypeMask.nonNullExact(closureClassElement, compiler.closedWorld); | |
| 1622 // TODO(efortuna): Add source information here. | |
| 1623 push(new HCreate(closureClassElement, capturedVariables, type)); | |
| 1624 | |
| 1625 registry?.registerInstantiatedClosure(methodElement); | |
| 1626 } | |
| 1627 | |
| 1565 // TODO(het): Decide when to inline | 1628 // TODO(het): Decide when to inline |
| 1566 @override | 1629 @override |
| 1567 void visitMethodInvocation(ir.MethodInvocation invocation) { | 1630 void visitMethodInvocation(ir.MethodInvocation invocation) { |
| 1568 // Handle `x == null` specially. When these come from null-aware operators, | 1631 // Handle `x == null` specially. When these come from null-aware operators, |
| 1569 // there is no mapping in the astAdapter. | 1632 // there is no mapping in the astAdapter. |
| 1570 if (_handleEqualsNull(invocation)) return; | 1633 if (_handleEqualsNull(invocation)) return; |
| 1571 invocation.receiver.accept(this); | 1634 invocation.receiver.accept(this); |
| 1572 HInstruction receiver = pop(); | 1635 HInstruction receiver = pop(); |
| 1573 | 1636 |
| 1574 _pushDynamicInvocation( | 1637 _pushDynamicInvocation( |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1725 push(new HNot(popBoolified(), backend.boolType)); | 1788 push(new HNot(popBoolified(), backend.boolType)); |
| 1726 } | 1789 } |
| 1727 | 1790 |
| 1728 @override | 1791 @override |
| 1729 void visitStringConcatenation(ir.StringConcatenation stringConcat) { | 1792 void visitStringConcatenation(ir.StringConcatenation stringConcat) { |
| 1730 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); | 1793 KernelStringBuilder stringBuilder = new KernelStringBuilder(this); |
| 1731 stringConcat.accept(stringBuilder); | 1794 stringConcat.accept(stringBuilder); |
| 1732 stack.add(stringBuilder.result); | 1795 stack.add(stringBuilder.result); |
| 1733 } | 1796 } |
| 1734 } | 1797 } |
| OLD | NEW |