|  | // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  | // Test various setter situations, testing special cases in optimizing compiler. | 
|  | // VMOptions=--optimization-counter-threshold=10 --no-use-osr | 
|  |  | 
|  | import "package:expect/expect.dart"; | 
|  |  | 
|  | class A { | 
|  | int field = 0; | 
|  | } | 
|  |  | 
|  | class B extends A {} | 
|  |  | 
|  | void sameImplicitSetter() { | 
|  | oneTarget(var a, var v) { | 
|  | a.field = v; | 
|  | } | 
|  |  | 
|  | A a = new A(); | 
|  | B b = new B(); | 
|  | // Optimize 'oneTarget' for one class, one target. | 
|  | for (int i = 0; i < 20; i++) { | 
|  | oneTarget(a, 5); | 
|  | Expect.equals(5, a.field); | 
|  | } | 
|  | // Deoptimize 'oneTarget', since class B is not expected. | 
|  | oneTarget(b, 6); | 
|  | Expect.equals(6, b.field); | 
|  | // Optimize 'oneTarget' for A and B classes, one target. | 
|  | for (int i = 0; i < 20; i++) { | 
|  | oneTarget(a, 7); | 
|  | Expect.equals(7, a.field); | 
|  | } | 
|  | oneTarget(b, 8); | 
|  | Expect.equals(8, b.field); | 
|  | } | 
|  |  | 
|  | // Deoptimize when no feedback exists. | 
|  | void setterNoFeedback() { | 
|  | maybeSet(var a, var v, bool set_it) { | 
|  | if (set_it) { | 
|  | return a.field = v; | 
|  | } | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | A a = new A(); | 
|  | for (int i = 0; i < 20; i++) { | 
|  | var r = maybeSet(a, 5, false); | 
|  | Expect.equals(0, a.field); | 
|  | Expect.equals(-1, r); | 
|  | } | 
|  | var r = maybeSet(a, 5, true); | 
|  | Expect.equals(5, a.field); | 
|  | Expect.equals(5, r); | 
|  | for (int i = 0; i < 20; i++) { | 
|  | var r = maybeSet(a, 6, true); | 
|  | Expect.equals(6, a.field); | 
|  | Expect.equals(6, r); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Check non-implicit setter | 
|  | class X { | 
|  | int pField = 0; | 
|  | set field(v) { | 
|  | pField = v; | 
|  | } | 
|  |  | 
|  | get field => 10; | 
|  | } | 
|  |  | 
|  | void sameNotImplicitSetter() { | 
|  | oneTarget(var a, var v) { | 
|  | return a.field = v; | 
|  | } | 
|  |  | 
|  | incField(var a) { | 
|  | a.field++; | 
|  | } | 
|  |  | 
|  | X x = new X(); | 
|  | for (int i = 0; i < 20; i++) { | 
|  | var r = oneTarget(x, 3); | 
|  | Expect.equals(3, x.pField); | 
|  | Expect.equals(3, r); | 
|  | } | 
|  | oneTarget(x, 0); | 
|  | for (int i = 0; i < 20; i++) { | 
|  | incField(x); | 
|  | } | 
|  | Expect.equals(11, x.pField); | 
|  | } | 
|  |  | 
|  | class Y { | 
|  | int field = 0; | 
|  | } | 
|  |  | 
|  | multiImplicitSetter() { | 
|  | oneTarget(var a, var v) { | 
|  | return a.field = v; | 
|  | } | 
|  |  | 
|  | // Both classes 'Y' and 'A' have a distinct field getter. | 
|  | A a = new A(); | 
|  | Y y = new Y(); | 
|  | for (int i = 0; i < 20; i++) { | 
|  | var r = oneTarget(a, 5); | 
|  | Expect.equals(5, a.field); | 
|  | Expect.equals(5, r); | 
|  | r = oneTarget(y, 6); | 
|  | Expect.equals(6, y.field); | 
|  | Expect.equals(6, r); | 
|  | } | 
|  | } | 
|  |  | 
|  | class Z { | 
|  | int pField = 0; | 
|  | set field(v) { | 
|  | pField = v; | 
|  | } | 
|  |  | 
|  | get field => 10; | 
|  | } | 
|  |  | 
|  | multiNotImplicitSetter() { | 
|  | oneTarget(var a, var v) { | 
|  | return a.field = v; | 
|  | } | 
|  |  | 
|  | Y y = new Y(); | 
|  | Z z = new Z(); | 
|  | for (int i = 0; i < 20; i++) { | 
|  | var r = oneTarget(y, 8); | 
|  | Expect.equals(8, y.field); | 
|  | Expect.equals(8, r); | 
|  | r = oneTarget(z, 12); | 
|  | Expect.equals(12, z.pField); | 
|  | Expect.equals(12, r); | 
|  | } | 
|  | A a = new A(); | 
|  | var r = oneTarget(a, 11); | 
|  | Expect.equals(11, a.field); | 
|  | Expect.equals(11, r); | 
|  | } | 
|  |  | 
|  | void main() { | 
|  | sameImplicitSetter(); | 
|  | setterNoFeedback(); | 
|  | sameNotImplicitSetter(); | 
|  |  | 
|  | multiImplicitSetter(); | 
|  | multiNotImplicitSetter(); | 
|  | } |