// Copyright (c) 2012, 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.

#include "vm/allocation.h"
#include "platform/assert.h"
#include "vm/longjump.h"
#include "vm/unit_test.h"

namespace dart {

class TestValueObject : public ValueObject {
 public:
  explicit TestValueObject(int* ptr) : ptr_(ptr) {
    EXPECT_EQ(1, *ptr_);
    *ptr_ = 2;
  }

  virtual ~TestValueObject() {
    EXPECT_EQ(3, *ptr_);
    *ptr_ = 4;
  }

  int value() const { return *ptr_; }
  virtual int GetId() const { return 3; }

 private:
  int* ptr_;
};

class TestStackResource : public StackResource {
 public:
  explicit TestStackResource(int* ptr)
      : StackResource(Thread::Current()), ptr_(ptr) {
    EXPECT_EQ(1, *ptr_);
    *ptr_ = 2;
  }

  ~TestStackResource() {
    EXPECT_EQ(6, *ptr_);
    *ptr_ = 7;
  }

  int value() const { return *ptr_; }
  virtual int GetId() const { return 3; }

 private:
  int* ptr_;
};

class TestStackedStackResource : public StackResource {
 public:
  explicit TestStackedStackResource(int* ptr)
      : StackResource(Thread::Current()), ptr_(ptr) {
    EXPECT_EQ(3, *ptr_);
    *ptr_ = 4;
  }

  ~TestStackedStackResource() {
    EXPECT_EQ(5, *ptr_);
    *ptr_ = 6;
  }

  int value() const { return *ptr_; }

 private:
  int* ptr_;
};

static void StackAllocatedDestructionHelper(int* ptr) {
  TestValueObject stacked(ptr);
  EXPECT_EQ(2, *ptr);
  *ptr = 3;
}

ISOLATE_UNIT_TEST_CASE(StackAllocatedDestruction) {
  int data = 1;
  StackAllocatedDestructionHelper(&data);
  EXPECT_EQ(4, data);
}

static void StackAllocatedLongJumpHelper(int* ptr, LongJumpScope* jump) {
  TestValueObject stacked(ptr);
  EXPECT_EQ(2, *ptr);
  *ptr = 3;
  const Error& error = Error::Handle(LanguageError::New(
      String::Handle(String::New("StackAllocatedLongJump"))));
  jump->Jump(1, error);
  UNREACHABLE();
}

ISOLATE_UNIT_TEST_CASE(StackAllocatedLongJump) {
  LongJumpScope jump;
  int data = 1;
  if (DART_SETJMP(*jump.Set()) == 0) {
    StackAllocatedLongJumpHelper(&data, &jump);
    UNREACHABLE();
  } else {
    ASSERT(Error::Handle(thread->StealStickyError()).IsLanguageError());
  }
  EXPECT_EQ(3, data);
}

static void StackedStackResourceDestructionHelper(int* ptr) {
  TestStackedStackResource stacked(ptr);
  EXPECT_EQ(4, *ptr);
  *ptr = 5;
}

static void StackResourceDestructionHelper(int* ptr) {
  TestStackResource stacked(ptr);
  EXPECT_EQ(2, *ptr);
  *ptr = 3;
  StackedStackResourceDestructionHelper(ptr);
  EXPECT_EQ(6, *ptr);
  // Do not set data because the LongJump version does not return control here.
}

ISOLATE_UNIT_TEST_CASE(StackResourceDestruction) {
  int data = 1;
  StackResourceDestructionHelper(&data);
  EXPECT_EQ(7, data);
}

static void StackedStackResourceLongJumpHelper(int* ptr, LongJumpScope* jump) {
  TestStackedStackResource stacked(ptr);
  EXPECT_EQ(4, *ptr);
  *ptr = 5;
  const Error& error = Error::Handle(LanguageError::New(
      String::Handle(String::New("StackedStackResourceLongJump"))));
  jump->Jump(1, error);
  UNREACHABLE();
}

static void StackResourceLongJumpHelper(int* ptr, LongJumpScope* jump) {
  TestStackResource stacked(ptr);
  EXPECT_EQ(2, *ptr);
  *ptr = 3;
  StackedStackResourceLongJumpHelper(ptr, jump);
  UNREACHABLE();
}

ISOLATE_UNIT_TEST_CASE(StackResourceLongJump) {
  LongJumpScope* base = Thread::Current()->long_jump_base();
  {
    LongJumpScope jump;
    int data = 1;
    if (DART_SETJMP(*jump.Set()) == 0) {
      StackResourceLongJumpHelper(&data, &jump);
      UNREACHABLE();
    } else {
      ASSERT(Error::Handle(thread->StealStickyError()).IsLanguageError());
    }
    EXPECT_EQ(7, data);
  }
  ASSERT(base == Thread::Current()->long_jump_base());
}

}  // namespace dart
