| 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 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 node.accept(this); | 1198 node.accept(this); |
| 1199 } | 1199 } |
| 1200 | 1200 |
| 1201 /// Returns the current source element. | 1201 /// Returns the current source element. |
| 1202 /// | 1202 /// |
| 1203 /// The returned element is a declaration element. | 1203 /// The returned element is a declaration element. |
| 1204 // TODO(johnniwinther): Check that all usages of sourceElement agree on | 1204 // TODO(johnniwinther): Check that all usages of sourceElement agree on |
| 1205 // implementation/declaration distinction. | 1205 // implementation/declaration distinction. |
| 1206 Element get sourceElement => sourceElementStack.last; | 1206 Element get sourceElement => sourceElementStack.last; |
| 1207 | 1207 |
| 1208 bool get _checkOrTrustTypes => | 1208 bool get _checkOrTrustTypes => compiler.options.enableTypeAssertions || |
| 1209 compiler.enableTypeAssertions || compiler.trustTypeAnnotations; | 1209 compiler.options.trustTypeAnnotations; |
| 1210 | 1210 |
| 1211 /// Build the graph for [target]. | 1211 /// Build the graph for [target]. |
| 1212 HGraph build() { | 1212 HGraph build() { |
| 1213 assert(invariant(target, target.isImplementation)); | 1213 assert(invariant(target, target.isImplementation)); |
| 1214 HInstruction.idCounter = 0; | 1214 HInstruction.idCounter = 0; |
| 1215 // TODO(sigmund): remove `result` and return graph directly, need to ensure | 1215 // TODO(sigmund): remove `result` and return graph directly, need to ensure |
| 1216 // that it can never be null (see result in buildFactory for instance). | 1216 // that it can never be null (see result in buildFactory for instance). |
| 1217 var result; | 1217 var result; |
| 1218 if (target.isGenerativeConstructor) { | 1218 if (target.isGenerativeConstructor) { |
| 1219 result = buildFactory(target); | 1219 result = buildFactory(target); |
| 1220 } else if (target.isGenerativeConstructorBody || | 1220 } else if (target.isGenerativeConstructorBody || |
| 1221 target.isFactoryConstructor || | 1221 target.isFactoryConstructor || |
| 1222 target.isFunction || | 1222 target.isFunction || |
| 1223 target.isGetter || | 1223 target.isGetter || |
| 1224 target.isSetter) { | 1224 target.isSetter) { |
| 1225 result = buildMethod(target); | 1225 result = buildMethod(target); |
| 1226 } else if (target.isField) { | 1226 } else if (target.isField) { |
| 1227 if (target.isInstanceMember) { | 1227 if (target.isInstanceMember) { |
| 1228 assert(compiler.enableTypeAssertions); | 1228 assert(compiler.options.enableTypeAssertions); |
| 1229 result = buildCheckedSetter(target); | 1229 result = buildCheckedSetter(target); |
| 1230 } else { | 1230 } else { |
| 1231 result = buildLazyInitializer(target); | 1231 result = buildLazyInitializer(target); |
| 1232 } | 1232 } |
| 1233 } else { | 1233 } else { |
| 1234 reporter.internalError(target, 'Unexpected element kind $target.'); | 1234 reporter.internalError(target, 'Unexpected element kind $target.'); |
| 1235 } | 1235 } |
| 1236 assert(result.isValid()); | 1236 assert(result.isValid()); |
| 1237 return result; | 1237 return result; |
| 1238 } | 1238 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1419 FunctionElement function = element; | 1419 FunctionElement function = element; |
| 1420 bool insideLoop = loopNesting > 0 || graph.calledInLoop; | 1420 bool insideLoop = loopNesting > 0 || graph.calledInLoop; |
| 1421 | 1421 |
| 1422 // Bail out early if the inlining decision is in the cache and we can't | 1422 // Bail out early if the inlining decision is in the cache and we can't |
| 1423 // inline (no need to check the hard constraints). | 1423 // inline (no need to check the hard constraints). |
| 1424 bool cachedCanBeInlined = | 1424 bool cachedCanBeInlined = |
| 1425 backend.inlineCache.canInline(function, insideLoop: insideLoop); | 1425 backend.inlineCache.canInline(function, insideLoop: insideLoop); |
| 1426 if (cachedCanBeInlined == false) return false; | 1426 if (cachedCanBeInlined == false) return false; |
| 1427 | 1427 |
| 1428 bool meetsHardConstraints() { | 1428 bool meetsHardConstraints() { |
| 1429 if (compiler.disableInlining) return false; | 1429 if (compiler.options.disableInlining) return false; |
| 1430 | 1430 |
| 1431 assert(invariant( | 1431 assert(invariant( |
| 1432 currentNode != null ? currentNode : element, | 1432 currentNode != null ? currentNode : element, |
| 1433 selector != null || | 1433 selector != null || |
| 1434 Elements.isStaticOrTopLevel(element) || | 1434 Elements.isStaticOrTopLevel(element) || |
| 1435 element.isGenerativeConstructorBody, | 1435 element.isGenerativeConstructorBody, |
| 1436 message: "Missing selector for inlining of $element.")); | 1436 message: "Missing selector for inlining of $element.")); |
| 1437 if (selector != null) { | 1437 if (selector != null) { |
| 1438 if (!selector.applies(function, compiler.world)) return false; | 1438 if (!selector.applies(function, compiler.world)) return false; |
| 1439 if (mask != null && !mask.canHit(function, selector, compiler.world)) { | 1439 if (mask != null && !mask.canHit(function, selector, compiler.world)) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1470 return false; | 1470 return false; |
| 1471 } | 1471 } |
| 1472 } | 1472 } |
| 1473 | 1473 |
| 1474 return true; | 1474 return true; |
| 1475 } | 1475 } |
| 1476 | 1476 |
| 1477 bool doesNotContainCode() { | 1477 bool doesNotContainCode() { |
| 1478 // A function with size 1 does not contain any code. | 1478 // A function with size 1 does not contain any code. |
| 1479 return InlineWeeder.canBeInlined(function, 1, true, | 1479 return InlineWeeder.canBeInlined(function, 1, true, |
| 1480 enableUserAssertions: compiler.enableUserAssertions); | 1480 enableUserAssertions: compiler.options.enableUserAssertions); |
| 1481 } | 1481 } |
| 1482 | 1482 |
| 1483 bool reductiveHeuristic() { | 1483 bool reductiveHeuristic() { |
| 1484 // The call is on a path which is executed rarely, so inline only if it | 1484 // The call is on a path which is executed rarely, so inline only if it |
| 1485 // does not make the program larger. | 1485 // does not make the program larger. |
| 1486 if (isCalledOnce(element)) { | 1486 if (isCalledOnce(element)) { |
| 1487 return InlineWeeder.canBeInlined(function, -1, false, | 1487 return InlineWeeder.canBeInlined(function, -1, false, |
| 1488 enableUserAssertions: compiler.enableUserAssertions); | 1488 enableUserAssertions: compiler.options.enableUserAssertions); |
| 1489 } | 1489 } |
| 1490 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable | 1490 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable |
| 1491 // case we miss by doing nothing is inlining very simple constructors | 1491 // case we miss by doing nothing is inlining very simple constructors |
| 1492 // where all fields are initialized with values from the arguments at this | 1492 // where all fields are initialized with values from the arguments at this |
| 1493 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but | 1493 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but |
| 1494 // that usually means the factory constructor is left unused and not | 1494 // that usually means the factory constructor is left unused and not |
| 1495 // emitted. | 1495 // emitted. |
| 1496 // We at least inline bodies that are empty (and thus have a size of 1). | 1496 // We at least inline bodies that are empty (and thus have a size of 1). |
| 1497 return doesNotContainCode(); | 1497 return doesNotContainCode(); |
| 1498 } | 1498 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1517 // Do not inline code that is rarely executed unless it reduces size. | 1517 // Do not inline code that is rarely executed unless it reduces size. |
| 1518 if (inExpressionOfThrow || inLazyInitializerExpression) { | 1518 if (inExpressionOfThrow || inLazyInitializerExpression) { |
| 1519 return reductiveHeuristic(); | 1519 return reductiveHeuristic(); |
| 1520 } | 1520 } |
| 1521 | 1521 |
| 1522 if (cachedCanBeInlined == true) { | 1522 if (cachedCanBeInlined == true) { |
| 1523 // We may have forced the inlining of some methods. Therefore check | 1523 // We may have forced the inlining of some methods. Therefore check |
| 1524 // if we can inline this method regardless of size. | 1524 // if we can inline this method regardless of size. |
| 1525 assert(InlineWeeder.canBeInlined(function, -1, false, | 1525 assert(InlineWeeder.canBeInlined(function, -1, false, |
| 1526 allowLoops: true, | 1526 allowLoops: true, |
| 1527 enableUserAssertions: compiler.enableUserAssertions)); | 1527 enableUserAssertions: compiler.options.enableUserAssertions)); |
| 1528 return true; | 1528 return true; |
| 1529 } | 1529 } |
| 1530 | 1530 |
| 1531 int numParameters = function.functionSignature.parameterCount; | 1531 int numParameters = function.functionSignature.parameterCount; |
| 1532 int maxInliningNodes; | 1532 int maxInliningNodes; |
| 1533 bool useMaxInliningNodes = true; | 1533 bool useMaxInliningNodes = true; |
| 1534 if (insideLoop) { | 1534 if (insideLoop) { |
| 1535 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + | 1535 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + |
| 1536 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; | 1536 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; |
| 1537 } else { | 1537 } else { |
| 1538 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + | 1538 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + |
| 1539 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; | 1539 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; |
| 1540 } | 1540 } |
| 1541 | 1541 |
| 1542 // If a method is called only once, and all the methods in the | 1542 // If a method is called only once, and all the methods in the |
| 1543 // inlining stack are called only once as well, we know we will | 1543 // inlining stack are called only once as well, we know we will |
| 1544 // save on output size by inlining this method. | 1544 // save on output size by inlining this method. |
| 1545 if (isCalledOnce(element)) { | 1545 if (isCalledOnce(element)) { |
| 1546 useMaxInliningNodes = false; | 1546 useMaxInliningNodes = false; |
| 1547 } | 1547 } |
| 1548 bool canInline; | 1548 bool canInline; |
| 1549 canInline = InlineWeeder.canBeInlined( | 1549 canInline = InlineWeeder.canBeInlined( |
| 1550 function, maxInliningNodes, useMaxInliningNodes, | 1550 function, maxInliningNodes, useMaxInliningNodes, |
| 1551 enableUserAssertions: compiler.enableUserAssertions); | 1551 enableUserAssertions: compiler.options.enableUserAssertions); |
| 1552 if (canInline) { | 1552 if (canInline) { |
| 1553 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); | 1553 backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop); |
| 1554 } else { | 1554 } else { |
| 1555 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); | 1555 backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop); |
| 1556 } | 1556 } |
| 1557 return canInline; | 1557 return canInline; |
| 1558 } | 1558 } |
| 1559 | 1559 |
| 1560 void doInlining() { | 1560 void doInlining() { |
| 1561 // Add an explicit null check on the receiver before doing the | 1561 // Add an explicit null check on the receiver before doing the |
| (...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2635 null, | 2635 null, |
| 2636 arguments); | 2636 arguments); |
| 2637 | 2637 |
| 2638 return new HTypeConversion(type, kind, original.instructionType, pop()); | 2638 return new HTypeConversion(type, kind, original.instructionType, pop()); |
| 2639 } else { | 2639 } else { |
| 2640 return original.convertType(compiler, type, kind); | 2640 return original.convertType(compiler, type, kind); |
| 2641 } | 2641 } |
| 2642 } | 2642 } |
| 2643 | 2643 |
| 2644 HInstruction _trustType(HInstruction original, DartType type) { | 2644 HInstruction _trustType(HInstruction original, DartType type) { |
| 2645 assert(compiler.trustTypeAnnotations); | 2645 assert(compiler.options.trustTypeAnnotations); |
| 2646 assert(type != null); | 2646 assert(type != null); |
| 2647 type = localsHandler.substInContext(type); | 2647 type = localsHandler.substInContext(type); |
| 2648 type = type.unaliased; | 2648 type = type.unaliased; |
| 2649 if (type.isDynamic) return original; | 2649 if (type.isDynamic) return original; |
| 2650 if (!type.isInterfaceType) return original; | 2650 if (!type.isInterfaceType) return original; |
| 2651 if (type.isObject) return original; | 2651 if (type.isObject) return original; |
| 2652 // The type element is either a class or the void element. | 2652 // The type element is either a class or the void element. |
| 2653 Element element = type.element; | 2653 Element element = type.element; |
| 2654 TypeMask mask = new TypeMask.subtype(element, compiler.world); | 2654 TypeMask mask = new TypeMask.subtype(element, compiler.world); |
| 2655 return new HTypeKnown.pinned(mask, original); | 2655 return new HTypeKnown.pinned(mask, original); |
| 2656 } | 2656 } |
| 2657 | 2657 |
| 2658 HInstruction _checkType(HInstruction original, DartType type, int kind) { | 2658 HInstruction _checkType(HInstruction original, DartType type, int kind) { |
| 2659 assert(compiler.enableTypeAssertions); | 2659 assert(compiler.options.enableTypeAssertions); |
| 2660 assert(type != null); | 2660 assert(type != null); |
| 2661 type = localsHandler.substInContext(type); | 2661 type = localsHandler.substInContext(type); |
| 2662 HInstruction other = buildTypeConversion(original, type, kind); | 2662 HInstruction other = buildTypeConversion(original, type, kind); |
| 2663 registry?.registerTypeUse(new TypeUse.isCheck(type)); | 2663 registry?.registerTypeUse(new TypeUse.isCheck(type)); |
| 2664 return other; | 2664 return other; |
| 2665 } | 2665 } |
| 2666 | 2666 |
| 2667 HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type, | 2667 HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type, |
| 2668 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { | 2668 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { |
| 2669 if (type == null) return original; | 2669 if (type == null) return original; |
| 2670 HInstruction checkedOrTrusted = original; | 2670 HInstruction checkedOrTrusted = original; |
| 2671 if (compiler.trustTypeAnnotations) { | 2671 if (compiler.options.trustTypeAnnotations) { |
| 2672 checkedOrTrusted = _trustType(original, type); | 2672 checkedOrTrusted = _trustType(original, type); |
| 2673 } else if (compiler.enableTypeAssertions) { | 2673 } else if (compiler.options.enableTypeAssertions) { |
| 2674 checkedOrTrusted = _checkType(original, type, kind); | 2674 checkedOrTrusted = _checkType(original, type, kind); |
| 2675 } | 2675 } |
| 2676 if (checkedOrTrusted == original) return original; | 2676 if (checkedOrTrusted == original) return original; |
| 2677 add(checkedOrTrusted); | 2677 add(checkedOrTrusted); |
| 2678 return checkedOrTrusted; | 2678 return checkedOrTrusted; |
| 2679 } | 2679 } |
| 2680 | 2680 |
| 2681 void assertIsSubtype(ast.Node node, DartType subtype, DartType supertype, | 2681 void assertIsSubtype(ast.Node node, DartType subtype, DartType supertype, |
| 2682 String message) { | 2682 String message) { |
| 2683 HInstruction subtypeInstruction = | 2683 HInstruction subtypeInstruction = |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2743 if (node != null) node.accept(this); | 2743 if (node != null) node.accept(this); |
| 2744 } | 2744 } |
| 2745 | 2745 |
| 2746 /// Visit [node] and pop the resulting [HInstruction]. | 2746 /// Visit [node] and pop the resulting [HInstruction]. |
| 2747 HInstruction visitAndPop(ast.Node node) { | 2747 HInstruction visitAndPop(ast.Node node) { |
| 2748 node.accept(this); | 2748 node.accept(this); |
| 2749 return pop(); | 2749 return pop(); |
| 2750 } | 2750 } |
| 2751 | 2751 |
| 2752 visitAssert(ast.Assert node) { | 2752 visitAssert(ast.Assert node) { |
| 2753 if (!compiler.enableUserAssertions) return; | 2753 if (!compiler.options.enableUserAssertions) return; |
| 2754 | 2754 |
| 2755 if (!node.hasMessage) { | 2755 if (!node.hasMessage) { |
| 2756 // Generate: | 2756 // Generate: |
| 2757 // | 2757 // |
| 2758 // assertHelper(condition); | 2758 // assertHelper(condition); |
| 2759 // | 2759 // |
| 2760 visit(node.condition); | 2760 visit(node.condition); |
| 2761 pushInvokeStatic(node, helpers.assertHelper, [pop()]); | 2761 pushInvokeStatic(node, helpers.assertHelper, [pop()]); |
| 2762 pop(); | 2762 pop(); |
| 2763 return; | 2763 return; |
| (...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4313 argument, MessageKind.GENERIC, | 4313 argument, MessageKind.GENERIC, |
| 4314 {'text': 'Error: Expected a literal string.'}); | 4314 {'text': 'Error: Expected a literal string.'}); |
| 4315 } | 4315 } |
| 4316 String name = string.dartString.slowToString(); | 4316 String name = string.dartString.slowToString(); |
| 4317 bool value = false; | 4317 bool value = false; |
| 4318 switch (name) { | 4318 switch (name) { |
| 4319 case 'MUST_RETAIN_METADATA': | 4319 case 'MUST_RETAIN_METADATA': |
| 4320 value = backend.mustRetainMetadata; | 4320 value = backend.mustRetainMetadata; |
| 4321 break; | 4321 break; |
| 4322 case 'USE_CONTENT_SECURITY_POLICY': | 4322 case 'USE_CONTENT_SECURITY_POLICY': |
| 4323 value = compiler.useContentSecurityPolicy; | 4323 value = compiler.options.useContentSecurityPolicy; |
| 4324 break; | 4324 break; |
| 4325 default: | 4325 default: |
| 4326 reporter.reportErrorMessage( | 4326 reporter.reportErrorMessage( |
| 4327 node, MessageKind.GENERIC, | 4327 node, MessageKind.GENERIC, |
| 4328 {'text': 'Error: Unknown internal flag "$name".'}); | 4328 {'text': 'Error: Unknown internal flag "$name".'}); |
| 4329 } | 4329 } |
| 4330 stack.add(graph.addConstantBool(value, compiler)); | 4330 stack.add(graph.addConstantBool(value, compiler)); |
| 4331 } | 4331 } |
| 4332 | 4332 |
| 4333 void handleForeignJsGetName(ast.Send node) { | 4333 void handleForeignJsGetName(ast.Send node) { |
| (...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5346 cls.typeVariables.length == expectedType.typeArguments.length); | 5346 cls.typeVariables.length == expectedType.typeArguments.length); |
| 5347 expectedType.typeArguments.forEach((DartType argument) { | 5347 expectedType.typeArguments.forEach((DartType argument) { |
| 5348 inputs.add(analyzeTypeArgument( | 5348 inputs.add(analyzeTypeArgument( |
| 5349 argument, sourceInformation: sourceInformation)); | 5349 argument, sourceInformation: sourceInformation)); |
| 5350 }); | 5350 }); |
| 5351 } | 5351 } |
| 5352 | 5352 |
| 5353 /// In checked mode checks the [type] of [node] to be well-bounded. The method | 5353 /// In checked mode checks the [type] of [node] to be well-bounded. The method |
| 5354 /// returns [:true:] if an error can be statically determined. | 5354 /// returns [:true:] if an error can be statically determined. |
| 5355 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) { | 5355 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) { |
| 5356 if (!compiler.enableTypeAssertions) return false; | 5356 if (!compiler.options.enableTypeAssertions) return false; |
| 5357 | 5357 |
| 5358 Map<DartType, Set<DartType>> seenChecksMap = | 5358 Map<DartType, Set<DartType>> seenChecksMap = |
| 5359 new Map<DartType, Set<DartType>>(); | 5359 new Map<DartType, Set<DartType>>(); |
| 5360 bool definitelyFails = false; | 5360 bool definitelyFails = false; |
| 5361 | 5361 |
| 5362 addTypeVariableBoundCheck(GenericType instance, | 5362 addTypeVariableBoundCheck(GenericType instance, |
| 5363 DartType typeArgument, | 5363 DartType typeArgument, |
| 5364 TypeVariableType typeVariable, | 5364 TypeVariableType typeVariable, |
| 5365 DartType bound) { | 5365 DartType bound) { |
| 5366 if (definitelyFails) return; | 5366 if (definitelyFails) return; |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5986 parameterNameMap[parameter.name] = | 5986 parameterNameMap[parameter.name] = |
| 5987 new js.InterpolatedExpression(positions++); | 5987 new js.InterpolatedExpression(positions++); |
| 5988 } | 5988 } |
| 5989 i++; | 5989 i++; |
| 5990 }); | 5990 }); |
| 5991 var codeTemplate = new js.Template(null, | 5991 var codeTemplate = new js.Template(null, |
| 5992 js.objectLiteral(parameterNameMap)); | 5992 js.objectLiteral(parameterNameMap)); |
| 5993 | 5993 |
| 5994 var nativeBehavior = new native.NativeBehavior() | 5994 var nativeBehavior = new native.NativeBehavior() |
| 5995 ..codeTemplate = codeTemplate; | 5995 ..codeTemplate = codeTemplate; |
| 5996 if (compiler.trustJSInteropTypeAnnotations) { | 5996 if (compiler.options.trustJSInteropTypeAnnotations) { |
| 5997 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); | 5997 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); |
| 5998 } | 5998 } |
| 5999 return new HForeignCode( | 5999 return new HForeignCode( |
| 6000 codeTemplate, | 6000 codeTemplate, |
| 6001 backend.dynamicType, filteredArguments, | 6001 backend.dynamicType, filteredArguments, |
| 6002 nativeBehavior: nativeBehavior) | 6002 nativeBehavior: nativeBehavior) |
| 6003 ..sourceInformation = sourceInformation; | 6003 ..sourceInformation = sourceInformation; |
| 6004 } | 6004 } |
| 6005 var target = new HForeignCode(js.js.parseForeignJS( | 6005 var target = new HForeignCode(js.js.parseForeignJS( |
| 6006 "${backend.namer.fixedBackendPath(element)}." | 6006 "${backend.namer.fixedBackendPath(element)}." |
| (...skipping 10 matching lines...) Expand all Loading... |
| 6017 | 6017 |
| 6018 var nativeBehavior = new native.NativeBehavior() | 6018 var nativeBehavior = new native.NativeBehavior() |
| 6019 ..sideEffects.setAllSideEffects(); | 6019 ..sideEffects.setAllSideEffects(); |
| 6020 | 6020 |
| 6021 DartType type = element.isConstructor ? | 6021 DartType type = element.isConstructor ? |
| 6022 element.enclosingClass.thisType : element.type.returnType; | 6022 element.enclosingClass.thisType : element.type.returnType; |
| 6023 // Native behavior effects here are similar to native/behavior.dart. | 6023 // Native behavior effects here are similar to native/behavior.dart. |
| 6024 // The return type is dynamic if we don't trust js-interop type | 6024 // The return type is dynamic if we don't trust js-interop type |
| 6025 // declarations. | 6025 // declarations. |
| 6026 nativeBehavior.typesReturned.add( | 6026 nativeBehavior.typesReturned.add( |
| 6027 compiler.trustJSInteropTypeAnnotations ? type : const DynamicType()); | 6027 compiler.options.trustJSInteropTypeAnnotations |
| 6028 ? type : const DynamicType()); |
| 6028 | 6029 |
| 6029 // The allocation effects include the declared type if it is native (which | 6030 // The allocation effects include the declared type if it is native (which |
| 6030 // includes js interop types). | 6031 // includes js interop types). |
| 6031 if (type.element != null && backend.isNative(type.element)) { | 6032 if (type.element != null && backend.isNative(type.element)) { |
| 6032 nativeBehavior.typesInstantiated.add(type); | 6033 nativeBehavior.typesInstantiated.add(type); |
| 6033 } | 6034 } |
| 6034 | 6035 |
| 6035 // It also includes any other JS interop type if we don't trust the | 6036 // It also includes any other JS interop type if we don't trust the |
| 6036 // annotation or if is declared too broad. | 6037 // annotation or if is declared too broad. |
| 6037 if (!compiler.trustJSInteropTypeAnnotations || type.isObject || | 6038 if (!compiler.options.trustJSInteropTypeAnnotations || type.isObject || |
| 6038 type.isDynamic) { | 6039 type.isDynamic) { |
| 6039 nativeBehavior.typesInstantiated.add( | 6040 nativeBehavior.typesInstantiated.add( |
| 6040 backend.helpers.jsJavaScriptObjectClass.thisType); | 6041 backend.helpers.jsJavaScriptObjectClass.thisType); |
| 6041 } | 6042 } |
| 6042 | 6043 |
| 6043 String code; | 6044 String code; |
| 6044 if (element.isGetter) { | 6045 if (element.isGetter) { |
| 6045 code = "#"; | 6046 code = "#"; |
| 6046 } else if (element.isSetter) { | 6047 } else if (element.isSetter) { |
| 6047 code = "# = #"; | 6048 code = "# = #"; |
| (...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7326 native.handleSsaNative(this, node.expression); | 7327 native.handleSsaNative(this, node.expression); |
| 7327 return; | 7328 return; |
| 7328 } | 7329 } |
| 7329 HInstruction value; | 7330 HInstruction value; |
| 7330 if (node.expression == null) { | 7331 if (node.expression == null) { |
| 7331 value = graph.addConstantNull(compiler); | 7332 value = graph.addConstantNull(compiler); |
| 7332 } else { | 7333 } else { |
| 7333 visit(node.expression); | 7334 visit(node.expression); |
| 7334 value = pop(); | 7335 value = pop(); |
| 7335 if (isBuildingAsyncFunction) { | 7336 if (isBuildingAsyncFunction) { |
| 7336 if (compiler.enableTypeAssertions && | 7337 if (compiler.options.enableTypeAssertions && |
| 7337 !isValidAsyncReturnType(returnType)) { | 7338 !isValidAsyncReturnType(returnType)) { |
| 7338 String message = | 7339 String message = |
| 7339 "Async function returned a Future, " | 7340 "Async function returned a Future, " |
| 7340 "was declared to return a $returnType."; | 7341 "was declared to return a $returnType."; |
| 7341 generateTypeError(node, message); | 7342 generateTypeError(node, message); |
| 7342 pop(); | 7343 pop(); |
| 7343 return; | 7344 return; |
| 7344 } | 7345 } |
| 7345 } else { | 7346 } else { |
| 7346 value = potentiallyCheckOrTrustType(value, returnType); | 7347 value = potentiallyCheckOrTrustType(value, returnType); |
| (...skipping 1976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9323 const _LoopTypeVisitor(); | 9324 const _LoopTypeVisitor(); |
| 9324 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; | 9325 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
| 9325 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; | 9326 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; |
| 9326 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; | 9327 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
| 9327 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; | 9328 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
| 9328 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 9329 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 9329 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 9330 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 9330 int visitSwitchStatement(ast.SwitchStatement node) => | 9331 int visitSwitchStatement(ast.SwitchStatement node) => |
| 9331 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 9332 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
| 9332 } | 9333 } |
| OLD | NEW |