// Copyright (c) 2013, 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 allocation sinking optimization.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation

import 'dart:typed_data';
import 'package:expect/expect.dart';

class Point {
  var x, y;

  Point(this.x, this.y);

  operator *(other) {
    return x * other.x + y * other.y;
  }
}

class C {
  var p;
  C(this.p);
}

class Pointx4 {
  var x, y;

  Pointx4(this.x, this.y);

  operator *(other) {
    return x * other.x + y * other.y;
  }
}

class Cx4 {
  var p;
  Cx4(this.p);
}

class D {
  var p;
  D(this.p);
}

// Class that is used to capture materialized Point object with * operator.
class F {
  var p;
  var val;

  F(this.p);

  operator *(other) {
    Expect.isTrue(other is Point);
    Expect.equals(42.0, other.x);
    Expect.equals(0.5, other.y);

    if (val == null) {
      val = other;
    } else {
      Expect.isTrue(identical(val, other));
    }

    return this.p * other;
  }
}

test1(c, x, y) {
  var a = new Point(x - 0.5, y + 0.5);
  var b = new Point(x + 0.5, y + 0.8);
  var d = new Point(c.p * a, c.p * b);
  return d * d;
}

test1x4(c, x, y, z, w) {
  var a = new Pointx4(x - z, y + w);
  var b = new Pointx4(x + w, y + z);
  var d = new Pointx4(c.p * a, c.p * b);
  return d * d;
}

effects() {
  // This function should not be inlinable.
  try {} catch (e) {}
}

testForwardingThroughEffects(c, x, y) {
  var a = new Point(x - 0.5, y + 0.5);
  var b = new Point(x - 0.5, y - 0.8);
  var d = new Point(c.p * a, c.p * b);
  // Effects can't affect neither a, b, nor d because they do not escape.
  effects();
  effects();
  return ((a == null) ? 0.0 : 0.1) + (d * d);
}

testIdentity(x) {
  var y = new Point(42.0, 0.5);
  var z = y;
  return x * y + x * z;
}

class PointP<T> {
  var x, y;

  PointP(this.x, this.y);

  operator *(other) {
    return x * other.x + y * other.y;
  }
}

foo2() => new PointP<int>(1, 3) * new PointP<num>(5, 6);

class A<T> {
  var x, y;
}

foo3(x) {
  // Test materialization of type arguments.
  var a = new A<int>();
  a.x = x;
  a.y = x;
  if (x is int) return a.x + a.y;
  Expect.isFalse(a is A<double>);
  Expect.isTrue(a is A<int>);
  Expect.isTrue(a is A);
  return a.x - a.y;
}

class WithFinal {
  final _x;
  WithFinal(this._x);
}

testInitialValueForFinalField(x) {
  new WithFinal(x);
}

testFinalField() {
  for (var i = 0; i < 100; i++) {
    testInitialValueForFinalField(1);
  }
}

class V {
  var x = 0;
}

test_vm_field() {
  var obj;
  inner() => obj.x = 42;
  var a = new V();
  obj = a;
  var t1 = a.x;
  var t2 = inner();
  return a.x + t1 + t2;
}

testVMField() {
  Expect.equals(84, test_vm_field());
  for (var i = 0; i < 100; i++) test_vm_field();
  Expect.equals(84, test_vm_field());
}

class CompoundA {
  var b;
  CompoundA(this.b);
}

class CompoundB {
  var c;
  CompoundB(this.c);
}

class CompoundC {
  var d;
  var root;
  CompoundC(this.d);
}

class NoopSink {
  const NoopSink();
  call(val) {}
}

testCompound1() {
  f(d, [sink = const NoopSink()]) {
    var c = new CompoundC(d);
    var a = new CompoundA(new CompoundB(c));
    sink(a);
    return c.d;
  }

  Expect.equals(0.1, f(0.1));
  for (var i = 0; i < 100; i++) f(0.1);
  Expect.equals(0.1, f(0.1));
  Expect.equals(
      0.1,
      f(0.1, (val) {
        Expect.isTrue(val is CompoundA);
        Expect.isTrue(val.b is CompoundB);
        Expect.isTrue(val.b.c is CompoundC);
        Expect.isNull(val.b.c.root);
        Expect.equals(0.1, val.b.c.d);
      }));
}

testCompound2() {
  f(d, [sink = const NoopSink()]) {
    var c = new CompoundC(d);
    var a = new CompoundA(new CompoundB(c));
    c.root = a;
    sink(a);
    return c.d;
  }

  Expect.equals(0.1, f(0.1));
  for (var i = 0; i < 100; i++) f(0.1);
  Expect.equals(0.1, f(0.1));
  Expect.equals(
      0.1,
      f(0.1, (val) {
        Expect.isTrue(val is CompoundA);
        Expect.isTrue(val.b is CompoundB);
        Expect.isTrue(val.b.c is CompoundC);
        Expect.equals(val, val.b.c.root);
        Expect.equals(0.1, val.b.c.d);
      }));
}

testCompound3() {
  f(d, [sink = const NoopSink()]) {
    var c = new CompoundC(d);
    c.root = c;
    sink(c);
    return c.d;
  }

  Expect.equals(0.1, f(0.1));
  for (var i = 0; i < 100; i++) f(0.1);
  Expect.equals(0.1, f(0.1));
  Expect.equals(
      0.1,
      f(0.1, (val) {
        Expect.isTrue(val is CompoundC);
        Expect.equals(val, val.root);
        Expect.equals(0.1, val.d);
      }));
}

testCompound4() {
  f(d, [sink = const NoopSink()]) {
    var c = new CompoundC(d);
    c.root = c;
    for (var i = 0; i < 10; i++) {
      c.d += 1.0;
    }
    sink(c);
    return c.d - 1.0 * 10;
  }

  Expect.equals(1.0, f(1.0));
  for (var i = 0; i < 100; i++) f(1.0);
  Expect.equals(1.0, f(1.0));
  Expect.equals(
      1.0,
      f(1.0, (val) {
        Expect.isTrue(val is CompoundC);
        Expect.equals(val, val.root);
        Expect.equals(11.0, val.d);
      }));
}

main() {
  var c = new C(new Point(0.1, 0.2));

  // Compute initial values.
  final x0 = test1(c, 11.11, 22.22);
  var fc = new Cx4(new Pointx4(
      new Float32x4(1.0, 1.0, 1.0, 1.0), new Float32x4(1.0, 1.0, 1.0, 1.0)));
  final fx0 = test1x4(
      fc,
      new Float32x4(1.0, 1.0, 1.0, 1.0),
      new Float32x4(1.0, 1.0, 1.0, 1.0),
      new Float32x4(1.0, 1.0, 1.0, 1.0),
      new Float32x4(1.0, 1.0, 1.0, 1.0));
  final y0 = testForwardingThroughEffects(c, 11.11, 22.22);
  final z0 = testIdentity(c.p);

  // Force optimization.
  for (var i = 0; i < 100; i++) {
    test1(c, i.toDouble(), i.toDouble());
    test1x4(
        fc,
        new Float32x4(1.0, 1.0, 1.0, 1.0),
        new Float32x4(1.0, 1.0, 1.0, 1.0),
        new Float32x4(1.0, 1.0, 1.0, 1.0),
        new Float32x4(1.0, 1.0, 1.0, 1.0));
    testForwardingThroughEffects(c, i.toDouble(), i.toDouble());
    testIdentity(c.p);
    foo2();
    Expect.equals(10, foo3(5));
  }
  Expect.equals(0.0, foo3(0.5));

  // Test returned value after optimization.
  final x1 = test1(c, 11.11, 22.22);
  final y1 = testForwardingThroughEffects(c, 11.11, 22.22);

  // Test returned value after deopt.
  final x2 = test1(new D(c.p), 11.11, 22.22);
  final y2 = testForwardingThroughEffects(new D(c.p), 11.11, 22.22);

  Expect.equals(6465, (x0 * 100).floor());
  Expect.equals(6465, (x1 * 100).floor());
  Expect.equals(6465, (x2 * 100).floor());
  Expect.equals(x0, x1);
  Expect.equals(x0, x2);

  Expect.equals(6008, (y0 * 100).floor());
  Expect.equals(6008, (y1 * 100).floor());
  Expect.equals(6008, (y2 * 100).floor());
  Expect.equals(y0, y1);
  Expect.equals(y0, y2);

  // Test that identity of materialized objects is preserved correctly and
  // no copies are materialized.
  final z1 = testIdentity(c.p);
  final z2 = testIdentity(new F(c.p));
  Expect.equals(z0, z1);
  Expect.equals(z0, z2);

  testFinalField();
  testVMField();
  testCompound1();
  testCompound2();
  testCompound3();
  testCompound4();
}
