// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/assembler.h"
#include "src/macro-assembler.h"
#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {

static void WriteRinfo(RelocInfoWriter* writer,
                       byte* pc, RelocInfo::Mode mode, intptr_t data) {
  RelocInfo rinfo(CcTest::i_isolate(), pc, mode, data, NULL);
  writer->Write(&rinfo);
}


// Tests that writing both types of positions and then reading either
// or both works as expected.
TEST(Positions) {
  CcTest::InitializeVM();
  const int code_size = 10 * KB;
  int relocation_info_size = 10 * KB;
  const int buffer_size = code_size + relocation_info_size;
  v8::base::SmartArrayPointer<byte> buffer(new byte[buffer_size]);

  byte* pc = buffer.get();
  byte* buffer_end = buffer.get() + buffer_size;

  RelocInfoWriter writer(buffer_end, pc);
  byte* relocation_info_end = buffer_end - relocation_info_size;
  for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
    RelocInfo::Mode mode = (i % 2 == 0) ?
        RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
    if (mode == RelocInfo::STATEMENT_POSITION) {
      printf("TEST WRITING STATEMENT %p %d\n", pc, pos);
    } else {
      printf("TEST WRITING POSITION %p %d\n", pc, pos);
    }
    WriteRinfo(&writer, pc, mode, pos);
    CHECK(writer.pos() - RelocInfoWriter::kMaxSize >= relocation_info_end);
  }

  writer.Finish();
  relocation_info_size = static_cast<int>(buffer_end - writer.pos());
  MacroAssembler assm(CcTest::i_isolate(), nullptr, 0, CodeObjectRequired::kNo);
  CodeDesc desc = {buffer.get(),         buffer_size, code_size,
                   relocation_info_size, 0,           &assm};

  // Read only (non-statement) positions.
  {
    RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::POSITION));
    pc = buffer.get();
    for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
      printf("TESTING 1: %d\n", i);
      RelocInfo::Mode mode = (i % 2 == 0) ?
          RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
      if (mode == RelocInfo::POSITION) {
        CHECK_EQ(pc, it.rinfo()->pc());
        CHECK_EQ(mode, it.rinfo()->rmode());
        CHECK_EQ(pos, static_cast<int>(it.rinfo()->data()));
        it.next();
      }
    }
    CHECK(it.done());
  }

  // Read only statement positions.
  {
    RelocIterator it(desc, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
    pc = buffer.get();
    for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
      RelocInfo::Mode mode = (i % 2 == 0) ?
          RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
      if (mode == RelocInfo::STATEMENT_POSITION) {
        CHECK_EQ(pc, it.rinfo()->pc());
        CHECK_EQ(mode, it.rinfo()->rmode());
        CHECK_EQ(pos, static_cast<int>(it.rinfo()->data()));
        it.next();
      }
    }
    CHECK(it.done());
  }

  // Read both types of positions.
  {
    RelocIterator it(desc, RelocInfo::kPositionMask);
    pc = buffer.get();
    for (int i = 0, pos = 0; i < 100; i++, pc += i, pos += i) {
      RelocInfo::Mode mode = (i % 2 == 0) ?
          RelocInfo::STATEMENT_POSITION : RelocInfo::POSITION;
      CHECK_EQ(pc, it.rinfo()->pc());
      CHECK_EQ(mode, it.rinfo()->rmode());
      CHECK_EQ(pos, static_cast<int>(it.rinfo()->data()));
      it.next();
    }
    CHECK(it.done());
  }
}

}  // namespace internal
}  // namespace v8
