Chromium Code Reviews| Index: pkg/compiler/lib/src/ssa/optimize.dart |
| diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart |
| index 5c6ec19ebf89fde870b1a0d6d10ffff330d6dfd3..9bf79b3b452b0a184f1b54127985793c7dc010fb 100644 |
| --- a/pkg/compiler/lib/src/ssa/optimize.dart |
| +++ b/pkg/compiler/lib/src/ssa/optimize.dart |
| @@ -1001,6 +1001,33 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
| return zapInstructionCache; |
| } |
| + /// Returns true of [foreign] will throw an noSuchMethod error if |
| + /// receiver is `null` before having any other side-effects. |
| + bool templateThrowsNSM(HForeignCode foreign, HInstruction receiver) { |
|
floitsch
2015/03/23 00:48:38
templateThrowsNsmOnNull
herhut
2015/03/24 11:31:43
Done.
|
| + // We look for a template of the form |
| + // |
| + // #.something -or- #.something() |
| + // |
| + // where # is substituted by receiver. |
| + js.Template template = foreign.codeTemplate; |
| + js.Node node = template.ast; |
| + // #.something = ... |
| + if (node is js.Assignment) { |
| + js.Assignment assignment = node; |
| + node = assignment.leftHandSide; |
| + } |
| + |
| + // #.something |
| + if (node is js.PropertyAccess) { |
| + js.PropertyAccess access = node; |
| + if (access.receiver is js.InterpolatedExpression) { |
| + js.InterpolatedExpression hole = access.receiver; |
| + return hole.isPositional && foreign.inputs.first == receiver; |
| + } |
| + } |
| + return false; |
| + } |
| + |
| /// Returns whether the next throwing instruction that may have side |
| /// effects after [instruction], throws [NoSuchMethodError] on the |
| /// same receiver of [instruction]. |
| @@ -1012,6 +1039,9 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
| && current.canThrow()) { |
| return true; |
| } |
| + if (current is HForeignCode && templateThrowsNSM(current, receiver)) { |
| + return true; |
| + } |
| if (current.canThrow() || current.sideEffects.hasSideEffects()) { |
| return false; |
| } |