// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/init/v8.h"

#include "src/codegen/source-position-table.h"
#include "src/objects/objects.h"
#include "test/unittests/test-utils.h"

namespace v8 {
namespace internal {
namespace interpreter {

class SourcePositionTableTest : public TestWithIsolate {
 public:
  SourcePositionTableTest() = default;
  ~SourcePositionTableTest() override = default;

  SourcePosition toPos(int offset) {
    return SourcePosition(offset, offset % 10 - 1);
  }
};

// Some random offsets, mostly at 'suspicious' bit boundaries.
static int offsets[] = {0,   1,   2,    3,    4,     30,      31,  32,
                        33,  62,  63,   64,   65,    126,     127, 128,
                        129, 250, 1000, 9999, 12000, 31415926};

TEST_F(SourcePositionTableTest, EncodeStatement) {
  SourcePositionTableBuilder builder;
  for (size_t i = 0; i < arraysize(offsets); i++) {
    builder.AddPosition(offsets[i], toPos(offsets[i]), true);
  }

  // To test correctness, we rely on the assertions in ToSourcePositionTable().
  // (Also below.)
  CHECK(!builder.ToSourcePositionTable(isolate()).is_null());
}

TEST_F(SourcePositionTableTest, EncodeStatementDuplicates) {
  SourcePositionTableBuilder builder;
  for (size_t i = 0; i < arraysize(offsets); i++) {
    builder.AddPosition(offsets[i], toPos(offsets[i]), true);
    builder.AddPosition(offsets[i], toPos(offsets[i] + 1), true);
  }

  // To test correctness, we rely on the assertions in ToSourcePositionTable().
  // (Also below.)
  CHECK(!builder.ToSourcePositionTable(isolate()).is_null());
}

TEST_F(SourcePositionTableTest, EncodeExpression) {
  SourcePositionTableBuilder builder;
  for (size_t i = 0; i < arraysize(offsets); i++) {
    builder.AddPosition(offsets[i], toPos(offsets[i]), false);
  }
  CHECK(!builder.ToSourcePositionTable(isolate()).is_null());
}

TEST_F(SourcePositionTableTest, EncodeAscending) {
  SourcePositionTableBuilder builder;

  int code_offset = 0;
  int source_position = 0;
  for (size_t i = 0; i < arraysize(offsets); i++) {
    code_offset += offsets[i];
    source_position += offsets[i];
    if (i % 2) {
      builder.AddPosition(code_offset, toPos(source_position), true);
    } else {
      builder.AddPosition(code_offset, toPos(source_position), false);
    }
  }

  // Also test negative offsets for source positions:
  for (size_t i = 0; i < arraysize(offsets); i++) {
    code_offset += offsets[i];
    source_position -= offsets[i];
    if (i % 2) {
      builder.AddPosition(code_offset, toPos(source_position), true);
    } else {
      builder.AddPosition(code_offset, toPos(source_position), false);
    }
  }

  CHECK(!builder.ToSourcePositionTable(isolate()).is_null());
}

}  // namespace interpreter
}  // namespace internal
}  // namespace v8
