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'; |
11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 11 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
12 import '../common/names.dart' show Identifiers, Selectors; | 12 import '../common/names.dart' show Identifiers, Selectors; |
13 import '../common/tasks.dart' show CompilerTask; | 13 import '../common/tasks.dart' show CompilerTask; |
14 import '../compiler.dart' show Compiler; | 14 import '../compiler.dart' show Compiler; |
15 import '../constants/constant_system.dart'; | 15 import '../constants/constant_system.dart'; |
16 import '../constants/expressions.dart'; | 16 import '../constants/expressions.dart'; |
17 import '../constants/values.dart'; | 17 import '../constants/values.dart'; |
18 import '../common_elements.dart' show CommonElements; | |
19 import '../elements/resolution_types.dart'; | 18 import '../elements/resolution_types.dart'; |
20 import '../diagnostics/messages.dart' show Message, MessageTemplate; | 19 import '../diagnostics/messages.dart' show Message, MessageTemplate; |
21 import '../dump_info.dart' show InfoReporter; | 20 import '../dump_info.dart' show InfoReporter; |
22 import '../elements/elements.dart'; | 21 import '../elements/elements.dart'; |
23 import '../elements/entities.dart'; | 22 import '../elements/entities.dart'; |
24 import '../elements/modelx.dart' show ConstructorBodyElementX; | 23 import '../elements/modelx.dart' show ConstructorBodyElementX; |
25 import '../io/source_information.dart'; | 24 import '../io/source_information.dart'; |
26 import '../js/js.dart' as js; | 25 import '../js/js.dart' as js; |
27 import '../js_backend/backend_helpers.dart' show BackendHelpers; | 26 import '../js_backend/backend_helpers.dart' show BackendHelpers; |
28 import '../js_backend/js_backend.dart'; | 27 import '../js_backend/js_backend.dart'; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 sourceInformationBuilder.buildVariableDeclaration(); | 219 sourceInformationBuilder.buildVariableDeclaration(); |
221 localsHandler = new LocalsHandler(this, target, null, compiler); | 220 localsHandler = new LocalsHandler(this, target, null, compiler); |
222 loopHandler = new SsaLoopHandler(this); | 221 loopHandler = new SsaLoopHandler(this); |
223 typeBuilder = new TypeBuilder(this); | 222 typeBuilder = new TypeBuilder(this); |
224 } | 223 } |
225 | 224 |
226 BackendHelpers get helpers => backend.helpers; | 225 BackendHelpers get helpers => backend.helpers; |
227 | 226 |
228 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; | 227 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; |
229 | 228 |
230 DiagnosticReporter get reporter => compiler.reporter; | |
231 | |
232 CommonElements get commonElements => closedWorld.commonElements; | |
233 | |
234 Element get targetElement => target; | 229 Element get targetElement => target; |
235 | 230 |
236 /// Reference to resolved elements in [target]'s AST. | 231 /// Reference to resolved elements in [target]'s AST. |
237 TreeElements get elements => resolvedAst.elements; | 232 TreeElements get elements => resolvedAst.elements; |
238 | 233 |
239 @override | 234 @override |
240 SemanticSendVisitor get sendVisitor => this; | 235 SemanticSendVisitor get sendVisitor => this; |
241 | 236 |
242 @override | 237 @override |
243 void visitNode(ast.Node node) { | 238 void visitNode(ast.Node node) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 if (target.isGenerativeConstructor) { | 273 if (target.isGenerativeConstructor) { |
279 result = buildFactory(resolvedAst); | 274 result = buildFactory(resolvedAst); |
280 } else if (target.isGenerativeConstructorBody || | 275 } else if (target.isGenerativeConstructorBody || |
281 target.isFactoryConstructor || | 276 target.isFactoryConstructor || |
282 target.isFunction || | 277 target.isFunction || |
283 target.isGetter || | 278 target.isGetter || |
284 target.isSetter) { | 279 target.isSetter) { |
285 result = buildMethod(target); | 280 result = buildMethod(target); |
286 } else if (target.isField) { | 281 } else if (target.isField) { |
287 if (target.isInstanceMember) { | 282 if (target.isInstanceMember) { |
288 assert(compiler.options.enableTypeAssertions); | 283 assert(options.enableTypeAssertions); |
289 result = buildCheckedSetter(target); | 284 result = buildCheckedSetter(target); |
290 } else { | 285 } else { |
291 result = buildLazyInitializer(target); | 286 result = buildLazyInitializer(target); |
292 } | 287 } |
293 } else { | 288 } else { |
294 reporter.internalError(target, 'Unexpected element kind $target.'); | 289 reporter.internalError(target, 'Unexpected element kind $target.'); |
295 } | 290 } |
296 assert(result.isValid()); | 291 assert(result.isValid()); |
297 return result; | 292 return result; |
298 } | 293 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 ResolvedAst functionResolvedAst = function.resolvedAst; | 415 ResolvedAst functionResolvedAst = function.resolvedAst; |
421 bool insideLoop = loopDepth > 0 || graph.calledInLoop; | 416 bool insideLoop = loopDepth > 0 || graph.calledInLoop; |
422 | 417 |
423 // Bail out early if the inlining decision is in the cache and we can't | 418 // Bail out early if the inlining decision is in the cache and we can't |
424 // inline (no need to check the hard constraints). | 419 // inline (no need to check the hard constraints). |
425 bool cachedCanBeInlined = | 420 bool cachedCanBeInlined = |
426 backend.inlineCache.canInline(function, insideLoop: insideLoop); | 421 backend.inlineCache.canInline(function, insideLoop: insideLoop); |
427 if (cachedCanBeInlined == false) return false; | 422 if (cachedCanBeInlined == false) return false; |
428 | 423 |
429 bool meetsHardConstraints() { | 424 bool meetsHardConstraints() { |
430 if (compiler.options.disableInlining) return false; | 425 if (options.disableInlining) return false; |
431 | 426 |
432 assert(invariant( | 427 assert(invariant( |
433 currentNode != null ? currentNode : function, | 428 currentNode != null ? currentNode : function, |
434 selector != null || | 429 selector != null || |
435 Elements.isStaticOrTopLevel(function) || | 430 Elements.isStaticOrTopLevel(function) || |
436 function.isGenerativeConstructorBody, | 431 function.isGenerativeConstructorBody, |
437 message: "Missing selector for inlining of $function.")); | 432 message: "Missing selector for inlining of $function.")); |
438 if (selector != null) { | 433 if (selector != null) { |
439 if (!selector.applies(function)) return false; | 434 if (!selector.applies(function)) return false; |
440 if (mask != null && !mask.canHit(function, selector, closedWorld)) { | 435 if (mask != null && !mask.canHit(function, selector, closedWorld)) { |
(...skipping 26 matching lines...) Expand all Loading... |
467 return false; | 462 return false; |
468 } | 463 } |
469 } | 464 } |
470 | 465 |
471 return true; | 466 return true; |
472 } | 467 } |
473 | 468 |
474 bool doesNotContainCode() { | 469 bool doesNotContainCode() { |
475 // A function with size 1 does not contain any code. | 470 // A function with size 1 does not contain any code. |
476 return InlineWeeder.canBeInlined(functionResolvedAst, 1, | 471 return InlineWeeder.canBeInlined(functionResolvedAst, 1, |
477 enableUserAssertions: compiler.options.enableUserAssertions); | 472 enableUserAssertions: options.enableUserAssertions); |
478 } | 473 } |
479 | 474 |
480 bool reductiveHeuristic() { | 475 bool reductiveHeuristic() { |
481 // The call is on a path which is executed rarely, so inline only if it | 476 // The call is on a path which is executed rarely, so inline only if it |
482 // does not make the program larger. | 477 // does not make the program larger. |
483 if (isCalledOnce(function)) { | 478 if (isCalledOnce(function)) { |
484 return InlineWeeder.canBeInlined(functionResolvedAst, null, | 479 return InlineWeeder.canBeInlined(functionResolvedAst, null, |
485 enableUserAssertions: compiler.options.enableUserAssertions); | 480 enableUserAssertions: options.enableUserAssertions); |
486 } | 481 } |
487 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable | 482 // TODO(sra): Measure if inlining would 'reduce' the size. One desirable |
488 // case we miss by doing nothing is inlining very simple constructors | 483 // case we miss by doing nothing is inlining very simple constructors |
489 // where all fields are initialized with values from the arguments at this | 484 // where all fields are initialized with values from the arguments at this |
490 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but | 485 // call site. The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but |
491 // that usually means the factory constructor is left unused and not | 486 // that usually means the factory constructor is left unused and not |
492 // emitted. | 487 // emitted. |
493 // We at least inline bodies that are empty (and thus have a size of 1). | 488 // We at least inline bodies that are empty (and thus have a size of 1). |
494 return doesNotContainCode(); | 489 return doesNotContainCode(); |
495 } | 490 } |
(...skipping 18 matching lines...) Expand all Loading... |
514 // Do not inline code that is rarely executed unless it reduces size. | 509 // Do not inline code that is rarely executed unless it reduces size. |
515 if (inExpressionOfThrow || inLazyInitializerExpression) { | 510 if (inExpressionOfThrow || inLazyInitializerExpression) { |
516 return reductiveHeuristic(); | 511 return reductiveHeuristic(); |
517 } | 512 } |
518 | 513 |
519 if (cachedCanBeInlined == true) { | 514 if (cachedCanBeInlined == true) { |
520 // We may have forced the inlining of some methods. Therefore check | 515 // We may have forced the inlining of some methods. Therefore check |
521 // if we can inline this method regardless of size. | 516 // if we can inline this method regardless of size. |
522 assert(InlineWeeder.canBeInlined(functionResolvedAst, null, | 517 assert(InlineWeeder.canBeInlined(functionResolvedAst, null, |
523 allowLoops: true, | 518 allowLoops: true, |
524 enableUserAssertions: compiler.options.enableUserAssertions)); | 519 enableUserAssertions: options.enableUserAssertions)); |
525 return true; | 520 return true; |
526 } | 521 } |
527 | 522 |
528 int numParameters = function.functionSignature.parameterCount; | 523 int numParameters = function.functionSignature.parameterCount; |
529 int maxInliningNodes; | 524 int maxInliningNodes; |
530 if (insideLoop) { | 525 if (insideLoop) { |
531 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + | 526 maxInliningNodes = InlineWeeder.INLINING_NODES_INSIDE_LOOP + |
532 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; | 527 InlineWeeder.INLINING_NODES_INSIDE_LOOP_ARG_FACTOR * numParameters; |
533 } else { | 528 } else { |
534 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + | 529 maxInliningNodes = InlineWeeder.INLINING_NODES_OUTSIDE_LOOP + |
535 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; | 530 InlineWeeder.INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR * numParameters; |
536 } | 531 } |
537 | 532 |
538 // If a method is called only once, and all the methods in the | 533 // If a method is called only once, and all the methods in the |
539 // inlining stack are called only once as well, we know we will | 534 // inlining stack are called only once as well, we know we will |
540 // save on output size by inlining this method. | 535 // save on output size by inlining this method. |
541 if (isCalledOnce(function)) { | 536 if (isCalledOnce(function)) { |
542 maxInliningNodes = null; | 537 maxInliningNodes = null; |
543 } | 538 } |
544 bool canInline = InlineWeeder.canBeInlined( | 539 bool canInline = InlineWeeder.canBeInlined( |
545 functionResolvedAst, maxInliningNodes, | 540 functionResolvedAst, maxInliningNodes, |
546 enableUserAssertions: compiler.options.enableUserAssertions); | 541 enableUserAssertions: options.enableUserAssertions); |
547 if (canInline) { | 542 if (canInline) { |
548 backend.inlineCache.markAsInlinable(function, insideLoop: insideLoop); | 543 backend.inlineCache.markAsInlinable(function, insideLoop: insideLoop); |
549 } else { | 544 } else { |
550 backend.inlineCache | 545 backend.inlineCache |
551 .markAsNonInlinable(function, insideLoop: insideLoop); | 546 .markAsNonInlinable(function, insideLoop: insideLoop); |
552 } | 547 } |
553 return canInline; | 548 return canInline; |
554 } | 549 } |
555 | 550 |
556 void doInlining() { | 551 void doInlining() { |
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 push(attachPosition(instruction, node)); | 1496 push(attachPosition(instruction, node)); |
1502 } | 1497 } |
1503 | 1498 |
1504 /// Pops the most recent instruction from the stack and 'boolifies' it. | 1499 /// Pops the most recent instruction from the stack and 'boolifies' it. |
1505 /// | 1500 /// |
1506 /// Boolification is checking if the value is '=== true'. | 1501 /// Boolification is checking if the value is '=== true'. |
1507 @override | 1502 @override |
1508 HInstruction popBoolified() { | 1503 HInstruction popBoolified() { |
1509 HInstruction value = pop(); | 1504 HInstruction value = pop(); |
1510 if (typeBuilder.checkOrTrustTypes) { | 1505 if (typeBuilder.checkOrTrustTypes) { |
1511 ResolutionInterfaceType boolType = compiler.commonElements.boolType; | 1506 ResolutionInterfaceType boolType = commonElements.boolType; |
1512 return typeBuilder.potentiallyCheckOrTrustType(value, boolType, | 1507 return typeBuilder.potentiallyCheckOrTrustType(value, boolType, |
1513 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); | 1508 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
1514 } | 1509 } |
1515 HInstruction result = new HBoolify(value, commonMasks.boolType); | 1510 HInstruction result = new HBoolify(value, commonMasks.boolType); |
1516 add(result); | 1511 add(result); |
1517 return result; | 1512 return result; |
1518 } | 1513 } |
1519 | 1514 |
1520 HInstruction attachPosition(HInstruction target, ast.Node node) { | 1515 HInstruction attachPosition(HInstruction target, ast.Node node) { |
1521 if (node != null) { | 1516 if (node != null) { |
1522 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); | 1517 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); |
1523 } | 1518 } |
1524 return target; | 1519 return target; |
1525 } | 1520 } |
1526 | 1521 |
1527 void visit(ast.Node node) { | 1522 void visit(ast.Node node) { |
1528 if (node != null) node.accept(this); | 1523 if (node != null) node.accept(this); |
1529 } | 1524 } |
1530 | 1525 |
1531 /// Visit [node] and pop the resulting [HInstruction]. | 1526 /// Visit [node] and pop the resulting [HInstruction]. |
1532 HInstruction visitAndPop(ast.Node node) { | 1527 HInstruction visitAndPop(ast.Node node) { |
1533 node.accept(this); | 1528 node.accept(this); |
1534 return pop(); | 1529 return pop(); |
1535 } | 1530 } |
1536 | 1531 |
1537 visitAssert(ast.Assert node) { | 1532 visitAssert(ast.Assert node) { |
1538 if (!compiler.options.enableUserAssertions) return; | 1533 if (!options.enableUserAssertions) return; |
1539 | 1534 |
1540 if (!node.hasMessage) { | 1535 if (!node.hasMessage) { |
1541 // Generate: | 1536 // Generate: |
1542 // | 1537 // |
1543 // assertHelper(condition); | 1538 // assertHelper(condition); |
1544 // | 1539 // |
1545 visit(node.condition); | 1540 visit(node.condition); |
1546 pushInvokeStatic(node, helpers.assertHelper, [pop()]); | 1541 pushInvokeStatic(node, helpers.assertHelper, [pop()]); |
1547 pop(); | 1542 pop(); |
1548 return; | 1543 return; |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 node, "SsaFromAstMixin.visitIdentifier on non-this."); | 1843 node, "SsaFromAstMixin.visitIdentifier on non-this."); |
1849 } | 1844 } |
1850 } | 1845 } |
1851 | 1846 |
1852 void handleIf( | 1847 void handleIf( |
1853 {ast.Node node, | 1848 {ast.Node node, |
1854 void visitCondition(), | 1849 void visitCondition(), |
1855 void visitThen(), | 1850 void visitThen(), |
1856 void visitElse(), | 1851 void visitElse(), |
1857 SourceInformation sourceInformation}) { | 1852 SourceInformation sourceInformation}) { |
1858 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, compiler, node); | 1853 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
1859 branchBuilder.handleIf(visitCondition, visitThen, visitElse, | 1854 branchBuilder.handleIf(visitCondition, visitThen, visitElse, |
1860 sourceInformation: sourceInformation); | 1855 sourceInformation: sourceInformation); |
1861 } | 1856 } |
1862 | 1857 |
1863 visitIf(ast.If node) { | 1858 visitIf(ast.If node) { |
1864 assert(isReachable); | 1859 assert(isReachable); |
1865 handleIf( | 1860 handleIf( |
1866 node: node, | 1861 node: node, |
1867 visitCondition: () => visit(node.condition), | 1862 visitCondition: () => visit(node.condition), |
1868 visitThen: () => visit(node.thenPart), | 1863 visitThen: () => visit(node.thenPart), |
1869 visitElse: node.elsePart != null ? () => visit(node.elsePart) : null, | 1864 visitElse: node.elsePart != null ? () => visit(node.elsePart) : null, |
1870 sourceInformation: sourceInformationBuilder.buildIf(node)); | 1865 sourceInformation: sourceInformationBuilder.buildIf(node)); |
1871 } | 1866 } |
1872 | 1867 |
1873 @override | 1868 @override |
1874 void visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) { | 1869 void visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) { |
1875 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 1870 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
1876 brancher.handleIfNull(() => visit(left), () => visit(right)); | 1871 brancher.handleIfNull(() => visit(left), () => visit(right)); |
1877 } | 1872 } |
1878 | 1873 |
1879 /// Optimizes logical binary where the left is also a logical binary. | 1874 /// Optimizes logical binary where the left is also a logical binary. |
1880 /// | 1875 /// |
1881 /// This method transforms the operator by optimizing the case where [left] is | 1876 /// This method transforms the operator by optimizing the case where [left] is |
1882 /// a logical "and" or logical "or". Then it uses [branchBuilder] to build the | 1877 /// a logical "and" or logical "or". Then it uses [branchBuilder] to build the |
1883 /// graph for the optimized expression. | 1878 /// graph for the optimized expression. |
1884 /// | 1879 /// |
1885 /// For example, `(x && y) && z` is transformed into `x && (y && z)`: | 1880 /// For example, `(x && y) && z` is transformed into `x && (y && z)`: |
(...skipping 24 matching lines...) Expand all Loading... |
1910 branchBuilder, | 1905 branchBuilder, |
1911 isAnd: isAnd); | 1906 isAnd: isAnd); |
1912 } else { | 1907 } else { |
1913 branchBuilder.handleLogicalBinary(() => visit(left), visitRight, | 1908 branchBuilder.handleLogicalBinary(() => visit(left), visitRight, |
1914 isAnd: isAnd); | 1909 isAnd: isAnd); |
1915 } | 1910 } |
1916 } | 1911 } |
1917 | 1912 |
1918 @override | 1913 @override |
1919 void visitLogicalAnd(ast.Send node, ast.Node left, ast.Node right, _) { | 1914 void visitLogicalAnd(ast.Send node, ast.Node left, ast.Node right, _) { |
1920 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, compiler, node); | 1915 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
1921 handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder, | 1916 handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder, |
1922 isAnd: true); | 1917 isAnd: true); |
1923 } | 1918 } |
1924 | 1919 |
1925 @override | 1920 @override |
1926 void visitLogicalOr(ast.Send node, ast.Node left, ast.Node right, _) { | 1921 void visitLogicalOr(ast.Send node, ast.Node left, ast.Node right, _) { |
1927 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, compiler, node); | 1922 SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, node); |
1928 handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder, | 1923 handleLogicalBinaryWithLeftNode(left, () => visit(right), branchBuilder, |
1929 isAnd: false); | 1924 isAnd: false); |
1930 } | 1925 } |
1931 | 1926 |
1932 @override | 1927 @override |
1933 void visitNot(ast.Send node, ast.Node expression, _) { | 1928 void visitNot(ast.Send node, ast.Node expression, _) { |
1934 assert(node.argumentsNode is ast.Prefix); | 1929 assert(node.argumentsNode is ast.Prefix); |
1935 visit(expression); | 1930 visit(expression); |
1936 SourceInformation sourceInformation = | 1931 SourceInformation sourceInformation = |
1937 sourceInformationBuilder.buildGeneric(node); | 1932 sourceInformationBuilder.buildGeneric(node); |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 @override | 2181 @override |
2187 void visitIfNotNullDynamicPropertyGet( | 2182 void visitIfNotNullDynamicPropertyGet( |
2188 ast.Send node, ast.Node receiver, Name name, _) { | 2183 ast.Send node, ast.Node receiver, Name name, _) { |
2189 // exp?.x compiled as: | 2184 // exp?.x compiled as: |
2190 // t1 = exp; | 2185 // t1 = exp; |
2191 // result = t1 == null ? t1 : t1.x; | 2186 // result = t1 == null ? t1 : t1.x; |
2192 // This is equivalent to t1 == null ? null : t1.x, but in the current form | 2187 // This is equivalent to t1 == null ? null : t1.x, but in the current form |
2193 // we will be able to later compress it as: | 2188 // we will be able to later compress it as: |
2194 // t1 || t1.x | 2189 // t1 || t1.x |
2195 HInstruction expression; | 2190 HInstruction expression; |
2196 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 2191 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
2197 brancher.handleConditional( | 2192 brancher.handleConditional( |
2198 () { | 2193 () { |
2199 expression = visitAndPop(receiver); | 2194 expression = visitAndPop(receiver); |
2200 pushCheckNull(expression); | 2195 pushCheckNull(expression); |
2201 }, | 2196 }, |
2202 () => stack.add(expression), | 2197 () => stack.add(expression), |
2203 () { | 2198 () { |
2204 generateInstanceGetterWithCompiledReceiver( | 2199 generateInstanceGetterWithCompiledReceiver( |
2205 node, | 2200 node, |
2206 elements.getSelector(node), | 2201 elements.getSelector(node), |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2545 visitDynamicPropertyInvoke(ast.Send node, ast.Node receiver, | 2540 visitDynamicPropertyInvoke(ast.Send node, ast.Node receiver, |
2546 ast.NodeList arguments, Selector selector, _) { | 2541 ast.NodeList arguments, Selector selector, _) { |
2547 generateDynamicSend(node); | 2542 generateDynamicSend(node); |
2548 } | 2543 } |
2549 | 2544 |
2550 @override | 2545 @override |
2551 visitIfNotNullDynamicPropertyInvoke(ast.Send node, ast.Node receiver, | 2546 visitIfNotNullDynamicPropertyInvoke(ast.Send node, ast.Node receiver, |
2552 ast.NodeList arguments, Selector selector, _) { | 2547 ast.NodeList arguments, Selector selector, _) { |
2553 /// Desugar `exp?.m()` to `(t1 = exp) == null ? t1 : t1.m()` | 2548 /// Desugar `exp?.m()` to `(t1 = exp) == null ? t1 : t1.m()` |
2554 HInstruction receiver; | 2549 HInstruction receiver; |
2555 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 2550 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
2556 brancher.handleConditional(() { | 2551 brancher.handleConditional(() { |
2557 receiver = generateInstanceSendReceiver(node); | 2552 receiver = generateInstanceSendReceiver(node); |
2558 pushCheckNull(receiver); | 2553 pushCheckNull(receiver); |
2559 }, () => stack.add(receiver), () => _generateDynamicSend(node, receiver)); | 2554 }, () => stack.add(receiver), () => _generateDynamicSend(node, receiver)); |
2560 } | 2555 } |
2561 | 2556 |
2562 @override | 2557 @override |
2563 visitThisPropertyInvoke( | 2558 visitThisPropertyInvoke( |
2564 ast.Send node, ast.NodeList arguments, Selector selector, _) { | 2559 ast.Send node, ast.NodeList arguments, Selector selector, _) { |
2565 generateDynamicSend(node); | 2560 generateDynamicSend(node); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2716 reporter.reportErrorMessage(argument, MessageKind.GENERIC, | 2711 reporter.reportErrorMessage(argument, MessageKind.GENERIC, |
2717 {'text': 'Error: Expected a literal string.'}); | 2712 {'text': 'Error: Expected a literal string.'}); |
2718 } | 2713 } |
2719 String name = string.dartString.slowToString(); | 2714 String name = string.dartString.slowToString(); |
2720 bool value = false; | 2715 bool value = false; |
2721 switch (name) { | 2716 switch (name) { |
2722 case 'MUST_RETAIN_METADATA': | 2717 case 'MUST_RETAIN_METADATA': |
2723 value = backend.mirrorsData.mustRetainMetadata; | 2718 value = backend.mirrorsData.mustRetainMetadata; |
2724 break; | 2719 break; |
2725 case 'USE_CONTENT_SECURITY_POLICY': | 2720 case 'USE_CONTENT_SECURITY_POLICY': |
2726 value = compiler.options.useContentSecurityPolicy; | 2721 value = options.useContentSecurityPolicy; |
2727 break; | 2722 break; |
2728 default: | 2723 default: |
2729 reporter.reportErrorMessage(node, MessageKind.GENERIC, | 2724 reporter.reportErrorMessage(node, MessageKind.GENERIC, |
2730 {'text': 'Error: Unknown internal flag "$name".'}); | 2725 {'text': 'Error: Unknown internal flag "$name".'}); |
2731 } | 2726 } |
2732 stack.add(graph.addConstantBool(value, closedWorld)); | 2727 stack.add(graph.addConstantBool(value, closedWorld)); |
2733 } | 2728 } |
2734 | 2729 |
2735 void handleForeignJsGetName(ast.Send node) { | 2730 void handleForeignJsGetName(ast.Send node) { |
2736 List<ast.Node> arguments = node.arguments.toList(); | 2731 List<ast.Node> arguments = node.arguments.toList(); |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3496 expectedType.typeArguments.forEach((ResolutionDartType argument) { | 3491 expectedType.typeArguments.forEach((ResolutionDartType argument) { |
3497 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement, | 3492 inputs.add(typeBuilder.analyzeTypeArgument(argument, sourceElement, |
3498 sourceInformation: sourceInformation)); | 3493 sourceInformation: sourceInformation)); |
3499 }); | 3494 }); |
3500 } | 3495 } |
3501 | 3496 |
3502 /// In checked mode checks the [type] of [node] to be well-bounded. The method | 3497 /// In checked mode checks the [type] of [node] to be well-bounded. The method |
3503 /// returns [:true:] if an error can be statically determined. | 3498 /// returns [:true:] if an error can be statically determined. |
3504 bool checkTypeVariableBounds( | 3499 bool checkTypeVariableBounds( |
3505 ast.NewExpression node, ResolutionInterfaceType type) { | 3500 ast.NewExpression node, ResolutionInterfaceType type) { |
3506 if (!compiler.options.enableTypeAssertions) return false; | 3501 if (!options.enableTypeAssertions) return false; |
3507 | 3502 |
3508 Map<ResolutionDartType, Set<ResolutionDartType>> seenChecksMap = | 3503 Map<ResolutionDartType, Set<ResolutionDartType>> seenChecksMap = |
3509 new Map<ResolutionDartType, Set<ResolutionDartType>>(); | 3504 new Map<ResolutionDartType, Set<ResolutionDartType>>(); |
3510 bool definitelyFails = false; | 3505 bool definitelyFails = false; |
3511 | 3506 |
3512 void addTypeVariableBoundCheck( | 3507 void addTypeVariableBoundCheck( |
3513 GenericType instance, | 3508 GenericType instance, |
3514 ResolutionDartType typeArgument, | 3509 ResolutionDartType typeArgument, |
3515 ResolutionTypeVariableType typeVariable, | 3510 ResolutionTypeVariableType typeVariable, |
3516 ResolutionDartType bound) { | 3511 ResolutionDartType bound) { |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3882 | 3877 |
3883 @override | 3878 @override |
3884 void bulkHandleNode(ast.Node node, String message, _) { | 3879 void bulkHandleNode(ast.Node node, String message, _) { |
3885 internalError(node, "Unexpected bulk handled node: $node"); | 3880 internalError(node, "Unexpected bulk handled node: $node"); |
3886 } | 3881 } |
3887 | 3882 |
3888 @override | 3883 @override |
3889 void bulkHandleNew(ast.NewExpression node, [_]) { | 3884 void bulkHandleNew(ast.NewExpression node, [_]) { |
3890 Element element = elements[node.send]; | 3885 Element element = elements[node.send]; |
3891 final bool isSymbolConstructor = | 3886 final bool isSymbolConstructor = |
3892 element == compiler.commonElements.symbolConstructor; | 3887 element == commonElements.symbolConstructor; |
3893 if (!Elements.isMalformed(element)) { | 3888 if (!Elements.isMalformed(element)) { |
3894 ConstructorElement function = element; | 3889 ConstructorElement function = element; |
3895 element = function.effectiveTarget; | 3890 element = function.effectiveTarget; |
3896 } | 3891 } |
3897 if (Elements.isError(element)) { | 3892 if (Elements.isError(element)) { |
3898 ErroneousElement error = element; | 3893 ErroneousElement error = element; |
3899 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR || | 3894 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR || |
3900 error.messageKind == MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR) { | 3895 error.messageKind == MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR) { |
3901 generateThrowNoSuchMethod( | 3896 generateThrowNoSuchMethod( |
3902 node.send, noSuchMethodTargetSymbolString(error, 'constructor'), | 3897 node.send, noSuchMethodTargetSymbolString(error, 'constructor'), |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4030 backend.nativeData.computeUnescapedJSInteropName(parameter.name); | 4025 backend.nativeData.computeUnescapedJSInteropName(parameter.name); |
4031 parameterNameMap[jsName] = new js.InterpolatedExpression(positions++); | 4026 parameterNameMap[jsName] = new js.InterpolatedExpression(positions++); |
4032 } | 4027 } |
4033 i++; | 4028 i++; |
4034 }); | 4029 }); |
4035 var codeTemplate = | 4030 var codeTemplate = |
4036 new js.Template(null, js.objectLiteral(parameterNameMap)); | 4031 new js.Template(null, js.objectLiteral(parameterNameMap)); |
4037 | 4032 |
4038 var nativeBehavior = new native.NativeBehavior() | 4033 var nativeBehavior = new native.NativeBehavior() |
4039 ..codeTemplate = codeTemplate; | 4034 ..codeTemplate = codeTemplate; |
4040 if (compiler.options.trustJSInteropTypeAnnotations) { | 4035 if (options.trustJSInteropTypeAnnotations) { |
4041 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); | 4036 nativeBehavior.typesReturned.add(constructor.enclosingClass.thisType); |
4042 } | 4037 } |
4043 return new HForeignCode( | 4038 return new HForeignCode( |
4044 codeTemplate, commonMasks.dynamicType, filteredArguments, | 4039 codeTemplate, commonMasks.dynamicType, filteredArguments, |
4045 nativeBehavior: nativeBehavior) | 4040 nativeBehavior: nativeBehavior) |
4046 ..sourceInformation = sourceInformation; | 4041 ..sourceInformation = sourceInformation; |
4047 } | 4042 } |
4048 var target = new HForeignCode( | 4043 var target = new HForeignCode( |
4049 js.js.parseForeignJS( | 4044 js.js.parseForeignJS( |
4050 "${backend.nativeData.getFixedBackendMethodPath(element)}." | 4045 "${backend.nativeData.getFixedBackendMethodPath(element)}." |
(...skipping 10 matching lines...) Expand all Loading... |
4061 | 4056 |
4062 var nativeBehavior = new native.NativeBehavior() | 4057 var nativeBehavior = new native.NativeBehavior() |
4063 ..sideEffects.setAllSideEffects(); | 4058 ..sideEffects.setAllSideEffects(); |
4064 | 4059 |
4065 ResolutionDartType type = element.isConstructor | 4060 ResolutionDartType type = element.isConstructor |
4066 ? element.enclosingClass.thisType | 4061 ? element.enclosingClass.thisType |
4067 : element.type.returnType; | 4062 : element.type.returnType; |
4068 // Native behavior effects here are similar to native/behavior.dart. | 4063 // Native behavior effects here are similar to native/behavior.dart. |
4069 // The return type is dynamic if we don't trust js-interop type | 4064 // The return type is dynamic if we don't trust js-interop type |
4070 // declarations. | 4065 // declarations. |
4071 nativeBehavior.typesReturned.add( | 4066 nativeBehavior.typesReturned.add(options.trustJSInteropTypeAnnotations |
4072 compiler.options.trustJSInteropTypeAnnotations | 4067 ? type |
4073 ? type | 4068 : const ResolutionDynamicType()); |
4074 : const ResolutionDynamicType()); | |
4075 | 4069 |
4076 // The allocation effects include the declared type if it is native (which | 4070 // The allocation effects include the declared type if it is native (which |
4077 // includes js interop types). | 4071 // includes js interop types). |
4078 if (type is ResolutionInterfaceType && | 4072 if (type is ResolutionInterfaceType && |
4079 backend.nativeData.isNativeClass(type.element)) { | 4073 backend.nativeData.isNativeClass(type.element)) { |
4080 nativeBehavior.typesInstantiated.add(type); | 4074 nativeBehavior.typesInstantiated.add(type); |
4081 } | 4075 } |
4082 | 4076 |
4083 // It also includes any other JS interop type if we don't trust the | 4077 // It also includes any other JS interop type if we don't trust the |
4084 // annotation or if is declared too broad. | 4078 // annotation or if is declared too broad. |
4085 if (!compiler.options.trustJSInteropTypeAnnotations || | 4079 if (!options.trustJSInteropTypeAnnotations || |
4086 type.isObject || | 4080 type.isObject || |
4087 type.isDynamic) { | 4081 type.isDynamic) { |
4088 ClassElement cls = backend.helpers.jsJavaScriptObjectClass; | 4082 ClassElement cls = backend.helpers.jsJavaScriptObjectClass; |
4089 nativeBehavior.typesInstantiated.add(cls.thisType); | 4083 nativeBehavior.typesInstantiated.add(cls.thisType); |
4090 } | 4084 } |
4091 | 4085 |
4092 String code; | 4086 String code; |
4093 if (element.isGetter) { | 4087 if (element.isGetter) { |
4094 code = "#"; | 4088 code = "#"; |
4095 } else if (element.isSetter) { | 4089 } else if (element.isSetter) { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4236 if (Elements.isUnresolved(getter)) { | 4230 if (Elements.isUnresolved(getter)) { |
4237 generateSuperNoSuchMethodSend(node, getterSelector, getterInputs); | 4231 generateSuperNoSuchMethodSend(node, getterSelector, getterInputs); |
4238 getterInstruction = pop(); | 4232 getterInstruction = pop(); |
4239 } else { | 4233 } else { |
4240 getterInstruction = | 4234 getterInstruction = |
4241 buildInvokeSuper(getterSelector, getter, getterInputs); | 4235 buildInvokeSuper(getterSelector, getter, getterInputs); |
4242 add(getterInstruction); | 4236 add(getterInstruction); |
4243 } | 4237 } |
4244 | 4238 |
4245 if (node.isIfNullAssignment) { | 4239 if (node.isIfNullAssignment) { |
4246 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 4240 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
4247 brancher.handleIfNull(() => stack.add(getterInstruction), () { | 4241 brancher.handleIfNull(() => stack.add(getterInstruction), () { |
4248 addDynamicSendArgumentsToList(node, setterInputs); | 4242 addDynamicSendArgumentsToList(node, setterInputs); |
4249 generateSuperSendSet(); | 4243 generateSuperSendSet(); |
4250 stack.add(setterInputs.last); | 4244 stack.add(setterInputs.last); |
4251 }); | 4245 }); |
4252 } else { | 4246 } else { |
4253 handleComplexOperatorSend(node, getterInstruction, arguments); | 4247 handleComplexOperatorSend(node, getterInstruction, arguments); |
4254 setterInputs.add(pop()); | 4248 setterInputs.add(pop()); |
4255 generateSuperSendSet(); | 4249 generateSuperSendSet(); |
4256 stack.add(node.isPostfix ? getterInstruction : setterInputs.last); | 4250 stack.add(node.isPostfix ? getterInstruction : setterInputs.last); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4556 | 4550 |
4557 pushInvokeDynamic(node, elements.getGetterSelectorInComplexSendSet(node), | 4551 pushInvokeDynamic(node, elements.getGetterSelectorInComplexSendSet(node), |
4558 elementInferenceResults.typeOfGetter(node), [receiver, index]); | 4552 elementInferenceResults.typeOfGetter(node), [receiver, index]); |
4559 HInstruction getterInstruction = pop(); | 4553 HInstruction getterInstruction = pop(); |
4560 if (node.isIfNullAssignment) { | 4554 if (node.isIfNullAssignment) { |
4561 // Compile x[i] ??= e as: | 4555 // Compile x[i] ??= e as: |
4562 // t1 = x[i] | 4556 // t1 = x[i] |
4563 // if (t1 == null) | 4557 // if (t1 == null) |
4564 // t1 = x[i] = e; | 4558 // t1 = x[i] = e; |
4565 // result = t1 | 4559 // result = t1 |
4566 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 4560 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
4567 brancher.handleIfNull(() => stack.add(getterInstruction), () { | 4561 brancher.handleIfNull(() => stack.add(getterInstruction), () { |
4568 visit(arguments.head); | 4562 visit(arguments.head); |
4569 HInstruction value = pop(); | 4563 HInstruction value = pop(); |
4570 pushInvokeDynamic( | 4564 pushInvokeDynamic( |
4571 node, | 4565 node, |
4572 elements.getSelector(node), | 4566 elements.getSelector(node), |
4573 elementInferenceResults.typeOfSend(node), | 4567 elementInferenceResults.typeOfSend(node), |
4574 [receiver, index, value]); | 4568 [receiver, index, value]); |
4575 pop(); | 4569 pop(); |
4576 stack.add(value); | 4570 stack.add(value); |
(...skipping 30 matching lines...) Expand all Loading... |
4607 void visitIfNotNullDynamicPropertySet( | 4601 void visitIfNotNullDynamicPropertySet( |
4608 ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) { | 4602 ast.SendSet node, ast.Node receiver, Name name, ast.Node rhs, _) { |
4609 // compile e?.x = e2 to: | 4603 // compile e?.x = e2 to: |
4610 // | 4604 // |
4611 // t1 = e | 4605 // t1 = e |
4612 // if (t1 == null) | 4606 // if (t1 == null) |
4613 // result = t1 // same as result = null | 4607 // result = t1 // same as result = null |
4614 // else | 4608 // else |
4615 // result = e.x = e2 | 4609 // result = e.x = e2 |
4616 HInstruction receiverInstruction; | 4610 HInstruction receiverInstruction; |
4617 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 4611 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
4618 brancher.handleConditional( | 4612 brancher.handleConditional( |
4619 () { | 4613 () { |
4620 receiverInstruction = generateInstanceSendReceiver(node); | 4614 receiverInstruction = generateInstanceSendReceiver(node); |
4621 pushCheckNull(receiverInstruction); | 4615 pushCheckNull(receiverInstruction); |
4622 }, | 4616 }, |
4623 () => stack.add(receiverInstruction), | 4617 () => stack.add(receiverInstruction), |
4624 () { | 4618 () { |
4625 generateInstanceSetterWithCompiledReceiver( | 4619 generateInstanceSetterWithCompiledReceiver( |
4626 node, receiverInstruction, visitAndPop(rhs)); | 4620 node, receiverInstruction, visitAndPop(rhs)); |
4627 }); | 4621 }); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4780 if (Elements.isInstanceSend(node, elements)) { | 4774 if (Elements.isInstanceSend(node, elements)) { |
4781 void generateAssignment(HInstruction receiver) { | 4775 void generateAssignment(HInstruction receiver) { |
4782 // desugars `e.x op= e2` to `e.x = e.x op e2` | 4776 // desugars `e.x op= e2` to `e.x = e.x op e2` |
4783 generateInstanceGetterWithCompiledReceiver( | 4777 generateInstanceGetterWithCompiledReceiver( |
4784 node, | 4778 node, |
4785 elements.getGetterSelectorInComplexSendSet(node), | 4779 elements.getGetterSelectorInComplexSendSet(node), |
4786 elementInferenceResults.typeOfGetter(node), | 4780 elementInferenceResults.typeOfGetter(node), |
4787 receiver); | 4781 receiver); |
4788 HInstruction getterInstruction = pop(); | 4782 HInstruction getterInstruction = pop(); |
4789 if (node.isIfNullAssignment) { | 4783 if (node.isIfNullAssignment) { |
4790 SsaBranchBuilder brancher = | 4784 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
4791 new SsaBranchBuilder(this, compiler, node); | |
4792 brancher.handleIfNull(() => stack.add(getterInstruction), () { | 4785 brancher.handleIfNull(() => stack.add(getterInstruction), () { |
4793 visit(node.arguments.head); | 4786 visit(node.arguments.head); |
4794 generateInstanceSetterWithCompiledReceiver(node, receiver, pop()); | 4787 generateInstanceSetterWithCompiledReceiver(node, receiver, pop()); |
4795 }); | 4788 }); |
4796 } else { | 4789 } else { |
4797 handleComplexOperatorSend(node, getterInstruction, node.arguments); | 4790 handleComplexOperatorSend(node, getterInstruction, node.arguments); |
4798 HInstruction value = pop(); | 4791 HInstruction value = pop(); |
4799 generateInstanceSetterWithCompiledReceiver(node, receiver, value); | 4792 generateInstanceSetterWithCompiledReceiver(node, receiver, value); |
4800 } | 4793 } |
4801 if (node.isPostfix) { | 4794 if (node.isPostfix) { |
4802 pop(); | 4795 pop(); |
4803 stack.add(getterInstruction); | 4796 stack.add(getterInstruction); |
4804 } | 4797 } |
4805 } | 4798 } |
4806 | 4799 |
4807 if (node.isConditional) { | 4800 if (node.isConditional) { |
4808 // generate `e?.x op= e2` as: | 4801 // generate `e?.x op= e2` as: |
4809 // t1 = e | 4802 // t1 = e |
4810 // t1 == null ? t1 : (t1.x = t1.x op e2); | 4803 // t1 == null ? t1 : (t1.x = t1.x op e2); |
4811 HInstruction receiver; | 4804 HInstruction receiver; |
4812 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 4805 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
4813 brancher.handleConditional(() { | 4806 brancher.handleConditional(() { |
4814 receiver = generateInstanceSendReceiver(node); | 4807 receiver = generateInstanceSendReceiver(node); |
4815 pushCheckNull(receiver); | 4808 pushCheckNull(receiver); |
4816 }, () => stack.add(receiver), () => generateAssignment(receiver)); | 4809 }, () => stack.add(receiver), () => generateAssignment(receiver)); |
4817 } else { | 4810 } else { |
4818 generateAssignment(generateInstanceSendReceiver(node)); | 4811 generateAssignment(generateInstanceSendReceiver(node)); |
4819 } | 4812 } |
4820 return; | 4813 return; |
4821 } | 4814 } |
4822 | 4815 |
4823 if (getter.isMalformed) { | 4816 if (getter.isMalformed) { |
4824 generateStaticUnresolvedGet(node, getter); | 4817 generateStaticUnresolvedGet(node, getter); |
4825 } else if (getter.isField) { | 4818 } else if (getter.isField) { |
4826 generateStaticFieldGet(node, getter); | 4819 generateStaticFieldGet(node, getter); |
4827 } else if (getter.isGetter) { | 4820 } else if (getter.isGetter) { |
4828 generateStaticGetterGet(node, getter); | 4821 generateStaticGetterGet(node, getter); |
4829 } else if (getter.isFunction) { | 4822 } else if (getter.isFunction) { |
4830 generateStaticFunctionGet(node, getter); | 4823 generateStaticFunctionGet(node, getter); |
4831 } else if (getter.isLocal) { | 4824 } else if (getter.isLocal) { |
4832 handleLocalGet(node, getter); | 4825 handleLocalGet(node, getter); |
4833 } else { | 4826 } else { |
4834 internalError(node, "Unexpected getter: $getter"); | 4827 internalError(node, "Unexpected getter: $getter"); |
4835 } | 4828 } |
4836 HInstruction getterInstruction = pop(); | 4829 HInstruction getterInstruction = pop(); |
4837 if (node.isIfNullAssignment) { | 4830 if (node.isIfNullAssignment) { |
4838 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 4831 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
4839 brancher.handleIfNull(() => stack.add(getterInstruction), () { | 4832 brancher.handleIfNull(() => stack.add(getterInstruction), () { |
4840 visit(node.arguments.head); | 4833 visit(node.arguments.head); |
4841 generateNonInstanceSetter(node, element, pop()); | 4834 generateNonInstanceSetter(node, element, pop()); |
4842 }); | 4835 }); |
4843 } else { | 4836 } else { |
4844 handleComplexOperatorSend(node, getterInstruction, node.arguments); | 4837 handleComplexOperatorSend(node, getterInstruction, node.arguments); |
4845 HInstruction value = pop(); | 4838 HInstruction value = pop(); |
4846 generateNonInstanceSetter(node, element, value); | 4839 generateNonInstanceSetter(node, element, value); |
4847 } | 4840 } |
4848 if (node.isPostfix) { | 4841 if (node.isPostfix) { |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5127 native.handleSsaNative(this, node.expression); | 5120 native.handleSsaNative(this, node.expression); |
5128 return; | 5121 return; |
5129 } | 5122 } |
5130 HInstruction value; | 5123 HInstruction value; |
5131 if (node.expression == null) { | 5124 if (node.expression == null) { |
5132 value = graph.addConstantNull(closedWorld); | 5125 value = graph.addConstantNull(closedWorld); |
5133 } else { | 5126 } else { |
5134 visit(node.expression); | 5127 visit(node.expression); |
5135 value = pop(); | 5128 value = pop(); |
5136 if (isBuildingAsyncFunction) { | 5129 if (isBuildingAsyncFunction) { |
5137 if (compiler.options.enableTypeAssertions && | 5130 if (options.enableTypeAssertions && |
5138 !isValidAsyncReturnType(returnType)) { | 5131 !isValidAsyncReturnType(returnType)) { |
5139 String message = "Async function returned a Future, " | 5132 String message = "Async function returned a Future, " |
5140 "was declared to return a $returnType."; | 5133 "was declared to return a $returnType."; |
5141 generateTypeError(node, message); | 5134 generateTypeError(node, message); |
5142 pop(); | 5135 pop(); |
5143 return; | 5136 return; |
5144 } | 5137 } |
5145 } else { | 5138 } else { |
5146 value = typeBuilder.potentiallyCheckOrTrustType(value, returnType); | 5139 value = typeBuilder.potentiallyCheckOrTrustType(value, returnType); |
5147 } | 5140 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5239 } | 5232 } |
5240 | 5233 |
5241 _inferredTypeOfNewList(ast.Send node) => | 5234 _inferredTypeOfNewList(ast.Send node) => |
5242 _resultOf(sourceElement).typeOfNewList(node) ?? commonMasks.dynamicType; | 5235 _resultOf(sourceElement).typeOfNewList(node) ?? commonMasks.dynamicType; |
5243 | 5236 |
5244 _inferredTypeOfListLiteral(ast.LiteralList node) => | 5237 _inferredTypeOfListLiteral(ast.LiteralList node) => |
5245 _resultOf(sourceElement).typeOfListLiteral(node) ?? | 5238 _resultOf(sourceElement).typeOfListLiteral(node) ?? |
5246 commonMasks.dynamicType; | 5239 commonMasks.dynamicType; |
5247 | 5240 |
5248 visitConditional(ast.Conditional node) { | 5241 visitConditional(ast.Conditional node) { |
5249 SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node); | 5242 SsaBranchBuilder brancher = new SsaBranchBuilder(this, node); |
5250 brancher.handleConditional(() => visit(node.condition), | 5243 brancher.handleConditional(() => visit(node.condition), |
5251 () => visit(node.thenExpression), () => visit(node.elseExpression)); | 5244 () => visit(node.thenExpression), () => visit(node.elseExpression)); |
5252 } | 5245 } |
5253 | 5246 |
5254 visitStringInterpolation(ast.StringInterpolation node) { | 5247 visitStringInterpolation(ast.StringInterpolation node) { |
5255 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); | 5248 StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node); |
5256 stringBuilder.visit(node); | 5249 stringBuilder.visit(node); |
5257 stack.add(stringBuilder.result); | 5250 stack.add(stringBuilder.result); |
5258 } | 5251 } |
5259 | 5252 |
5260 visitStringInterpolationPart(ast.StringInterpolationPart node) { | 5253 visitStringInterpolationPart(ast.StringInterpolationPart node) { |
5261 // The parts are iterated in visitStringInterpolation. | 5254 // The parts are iterated in visitStringInterpolation. |
5262 reporter.internalError( | 5255 reporter.internalError( |
5263 node, 'SsaBuilder.visitStringInterpolation should not be called.'); | 5256 node, 'SsaBuilder.visitStringInterpolation should not be called.'); |
5264 } | 5257 } |
5265 | 5258 |
5266 visitEmptyStatement(ast.EmptyStatement node) { | 5259 visitEmptyStatement(ast.EmptyStatement node) { |
5267 // Do nothing, empty statement. | 5260 // Do nothing, empty statement. |
5268 } | 5261 } |
5269 | 5262 |
5270 visitModifiers(ast.Modifiers node) { | 5263 visitModifiers(ast.Modifiers node) { |
5271 compiler.unimplemented(node, 'SsaFromAstMixin.visitModifiers.'); | 5264 throw new SpannableAssertionFailure( |
| 5265 node, 'SsaFromAstMixin.visitModifiers not implemented.'); |
5272 } | 5266 } |
5273 | 5267 |
5274 visitBreakStatement(ast.BreakStatement node) { | 5268 visitBreakStatement(ast.BreakStatement node) { |
5275 assert(!isAborted()); | 5269 assert(!isAborted()); |
5276 handleInTryStatement(); | 5270 handleInTryStatement(); |
5277 JumpTarget target = elements.getTargetOf(node); | 5271 JumpTarget target = elements.getTargetOf(node); |
5278 assert(target != null); | 5272 assert(target != null); |
5279 JumpHandler handler = jumpTargets[target]; | 5273 JumpHandler handler = jumpTargets[target]; |
5280 assert(handler != null); | 5274 assert(handler != null); |
5281 if (node.target == null) { | 5275 if (node.target == null) { |
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6363 wrapStatementGraph(catchGraph), wrapStatementGraph(finallyGraph)), | 6357 wrapStatementGraph(catchGraph), wrapStatementGraph(finallyGraph)), |
6364 exitBlock); | 6358 exitBlock); |
6365 inTryStatement = oldInTryStatement; | 6359 inTryStatement = oldInTryStatement; |
6366 } | 6360 } |
6367 | 6361 |
6368 visitCatchBlock(ast.CatchBlock node) { | 6362 visitCatchBlock(ast.CatchBlock node) { |
6369 visit(node.block); | 6363 visit(node.block); |
6370 } | 6364 } |
6371 | 6365 |
6372 visitTypedef(ast.Typedef node) { | 6366 visitTypedef(ast.Typedef node) { |
6373 compiler.unimplemented(node, 'SsaFromAstMixin.visitTypedef.'); | 6367 throw new SpannableAssertionFailure( |
| 6368 node, 'SsaFromAstMixin.visitTypedef not implemented.'); |
6374 } | 6369 } |
6375 | 6370 |
6376 visitTypeVariable(ast.TypeVariable node) { | 6371 visitTypeVariable(ast.TypeVariable node) { |
6377 reporter.internalError(node, 'SsaFromAstMixin.visitTypeVariable.'); | 6372 throw new SpannableAssertionFailure( |
| 6373 node, 'SsaFromAstMixin.visitTypeVariable not implemented.'); |
6378 } | 6374 } |
6379 | 6375 |
6380 /** | 6376 /** |
6381 * This method is invoked before inlining the body of [function] into this | 6377 * This method is invoked before inlining the body of [function] into this |
6382 * [SsaBuilder]. | 6378 * [SsaBuilder]. |
6383 */ | 6379 */ |
6384 void enterInlinedMethod(MethodElement function, | 6380 void enterInlinedMethod(MethodElement function, |
6385 ResolvedAst functionResolvedAst, List<HInstruction> compiledArguments, | 6381 ResolvedAst functionResolvedAst, List<HInstruction> compiledArguments, |
6386 {ResolutionInterfaceType instanceType}) { | 6382 {ResolutionInterfaceType instanceType}) { |
6387 AstInliningState state = new AstInliningState( | 6383 AstInliningState state = new AstInliningState( |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6483 final SsaBuilder builder; | 6479 final SsaBuilder builder; |
6484 final ast.Node diagnosticNode; | 6480 final ast.Node diagnosticNode; |
6485 | 6481 |
6486 /** | 6482 /** |
6487 * The string value generated so far. | 6483 * The string value generated so far. |
6488 */ | 6484 */ |
6489 HInstruction result = null; | 6485 HInstruction result = null; |
6490 | 6486 |
6491 StringBuilderVisitor(this.builder, this.diagnosticNode); | 6487 StringBuilderVisitor(this.builder, this.diagnosticNode); |
6492 | 6488 |
6493 Compiler get compiler => builder.compiler; | |
6494 | |
6495 void visit(ast.Node node) { | 6489 void visit(ast.Node node) { |
6496 node.accept(this); | 6490 node.accept(this); |
6497 } | 6491 } |
6498 | 6492 |
6499 visitNode(ast.Node node) { | 6493 visitNode(ast.Node node) { |
6500 builder.reporter.internalError(node, 'Unexpected node.'); | 6494 builder.reporter.internalError(node, 'Unexpected node.'); |
6501 } | 6495 } |
6502 | 6496 |
6503 void visitExpression(ast.Node node) { | 6497 void visitExpression(ast.Node node) { |
6504 node.accept(builder); | 6498 node.accept(builder); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6760 this.oldReturnLocal, | 6754 this.oldReturnLocal, |
6761 this.oldReturnType, | 6755 this.oldReturnType, |
6762 this.oldResolvedAst, | 6756 this.oldResolvedAst, |
6763 this.oldStack, | 6757 this.oldStack, |
6764 this.oldLocalsHandler, | 6758 this.oldLocalsHandler, |
6765 this.inTryStatement, | 6759 this.inTryStatement, |
6766 this.allFunctionsCalledOnce, | 6760 this.allFunctionsCalledOnce, |
6767 this.oldElementInferenceResults) | 6761 this.oldElementInferenceResults) |
6768 : super(function); | 6762 : super(function); |
6769 } | 6763 } |
OLD | NEW |