// Copyright 2015 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/api/api-inl.h"
#include "src/compiler/pipeline.h"
#include "src/execution/isolate.h"
#include "src/handles/handles.h"
#include "src/interpreter/bytecode-generator.h"
#include "src/interpreter/interpreter.h"
#include "src/objects/objects-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/interpreter/source-position-matcher.h"

namespace v8 {
namespace internal {
namespace interpreter {

// Flags enabling optimizations that change generated bytecode array.
// Format is <command-line flag> <flag name> <bit index>
#define OPTIMIZATION_FLAGS(V)      \
  V(FLAG_ignition_reo, kUseReo, 0) \
  V(FLAG_ignition_filter_expression_positions, kUseFilterExpressionPositions, 2)

#define DECLARE_BIT(_, Name, BitIndex) static const int Name = 1 << BitIndex;
OPTIMIZATION_FLAGS(DECLARE_BIT)
#undef DECLARE_BIT

// Test cases source positions are checked for. Please ensure all
// combinations of flags are present here. This is done manually
// because it provides easier to comprehend failure case for humans.
#define TEST_CASES(V)                                              \
  V(UsingReo, kUseReo)                                             \
  V(UsingFilterExpressionPositions, kUseFilterExpressionPositions) \
  V(UsingAllOptimizations, kUseReo | kUseFilterExpressionPositions)

struct TestCaseData {
  TestCaseData(const char* const script,
               const char* const declaration_parameters = "",
               const char* const arguments = "")
      : script_(script),
        declaration_parameters_(declaration_parameters),
        arguments_(arguments) {}

  const char* script() const { return script_; }
  const char* declaration_parameters() const { return declaration_parameters_; }
  const char* arguments() const { return arguments_; }

 private:
  TestCaseData() = delete;

  const char* const script_;
  const char* const declaration_parameters_;
  const char* const arguments_;
};

static const TestCaseData kTestCaseData[] = {
    {"var x = (y = 3) + (x = y); return x + y;"},
    {"var x = 55;\n"
     "var y = x + (x = 1) + (x = 2) + (x = 3);\n"
     "return y;"},
    {"var x = 10; return x >>> 3;\n"},
    {"var x = 0; return x || (1, 2, 3);\n"},
    {"return a || (a, b, a, b, c = 5, 3);\n"},
    {"var a = 3; var b = 4; a = b; b = a; a = b; return a;\n"},
    {"var a = 1; return [[a, 2], [a + 2]];\n"},
    {"var a = 1; if (a || a < 0) { return 1; }\n"},
    {"var b;"
     "b = a.name;"
     "b = a.name;"
     "a.name = a;"
     "b = a.name;"
     "a.name = a;"
     "return b;"},
    {"var sum = 0;\n"
     "outer: {\n"
     "  for (var x = 0; x < 10; ++x) {\n"
     "    for (var y = 0; y < 3; ++y) {\n"
     "      ++sum;\n"
     "      if (x + y == 12) { break outer; }\n"
     "    }\n"
     "  }\n"
     "}\n"
     "return sum;\n"},
    {"var a = 1;"
     "switch (a) {"
     "  case 1: return a * a + 1;"
     "  case 1: break;"
     "  case 2: return (a = 3) * a + (a = 4);"
     "  case 3:"
     "}"
     "return a;"},
    {"for (var p of [0, 1, 2]) {}"},
    {"var x = { 'a': 1, 'b': 2 };"
     "for (x['a'] of [1,2,3]) { return x['a']; }"},
    {"while (x == 4) {\n"
     "  var y = x + 1;\n"
     "  if (y == 2) break;\n"
     "  for (z['a'] of [0]) {\n"
     "    x += (x *= 3) + y;"
     "  }\n"
     "}\n"},
    {"function g(a, b) { return a.func(b + b, b); }\n"
     "g(new (function Obj() { this.func = function() { return; }})(), 1)\n"},
    {"return some_global[name];", "name", "'a'"}};

class OptimizedBytecodeSourcePositionTester final {
 public:
  explicit OptimizedBytecodeSourcePositionTester(Isolate* isolate)
      : isolate_(isolate) {
    SaveOptimizationFlags();
    saved_flag_always_opt_ = FLAG_always_opt;
    FLAG_always_opt = false;
    FLAG_enable_lazy_source_positions = false;
  }

  ~OptimizedBytecodeSourcePositionTester() {
    RestoreOptimizationFlags();
    FLAG_always_opt = saved_flag_always_opt_;
  }

  bool SourcePositionsMatch(int optimization_bitmap, const char* function_body,
                            const char* function_decl_params,
                            const char* function_args);

 private:
  Handle<BytecodeArray> MakeBytecode(int optimization_bitmap,
                                     const char* function_body,
                                     const char* function_decl_params,
                                     const char* function_args);
  static std::string MakeScript(const char* function_body,
                                const char* function_decl_params,
                                const char* function_args);

  void SetOptimizationFlags(int optimization_bitmap);
  void SaveOptimizationFlags();
  void RestoreOptimizationFlags();

  Isolate* isolate() const { return isolate_; }

  Isolate* isolate_;
  int saved_optimization_bitmap_;
  bool saved_flag_always_opt_;
};

// static
std::string OptimizedBytecodeSourcePositionTester::MakeScript(
    const char* function_body, const char* function_decl_params,
    const char* function_args) {
  std::ostringstream os;
  os << "function test_function"
     << "(" << function_decl_params << ") {";
  os << function_body;
  os << "}";
  os << "test_function(" << function_args << ");";
  return os.str();
}

Handle<BytecodeArray> OptimizedBytecodeSourcePositionTester::MakeBytecode(
    int optimization_bitmap, const char* function_body,
    const char* function_decl_params, const char* function_args) {
  std::string script =
      MakeScript(function_body, function_decl_params, function_args);
  SetOptimizationFlags(optimization_bitmap);
  CompileRun(script.c_str());

  Local<Function> api_function = Local<Function>::Cast(
      CcTest::global()
          ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("test_function"))
          .ToLocalChecked());
  Handle<JSFunction> function =
      Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
  return handle(function->shared().GetBytecodeArray(), isolate_);
}

void OptimizedBytecodeSourcePositionTester::SetOptimizationFlags(
    int optimization_bitmap) {
#define SET_FLAG(V8Flag, BitName, _) \
  V8Flag = (optimization_bitmap & BitName) ? true : false;
  OPTIMIZATION_FLAGS(SET_FLAG)
#undef SET_FLAG
}

void OptimizedBytecodeSourcePositionTester::SaveOptimizationFlags() {
  saved_optimization_bitmap_ = 0;
#define SAVE_FLAG(V8Flag, BitName, _) \
  if (V8Flag) saved_optimization_bitmap_ |= BitName;
#undef SET_FLAG
}

void OptimizedBytecodeSourcePositionTester::RestoreOptimizationFlags() {
  SetOptimizationFlags(saved_optimization_bitmap_);
}

bool OptimizedBytecodeSourcePositionTester::SourcePositionsMatch(
    int optimization_bitmap, const char* function_body,
    const char* function_decl_params, const char* function_args) {
  Handle<BytecodeArray> unoptimized_bytecode =
      MakeBytecode(0, function_body, function_decl_params, function_args);
  Handle<BytecodeArray> optimized_bytecode = MakeBytecode(
      optimization_bitmap, function_body, function_decl_params, function_args);
  SourcePositionMatcher matcher;
  if (!matcher.Match(unoptimized_bytecode, optimized_bytecode)) {
    return false;
  }
  return true;
}

void TestSourcePositionsEquivalent(int optimization_bitmap) {
  HandleAndZoneScope handles;
  OptimizedBytecodeSourcePositionTester tester(handles.main_isolate());
  for (auto test_case_data : kTestCaseData) {
    CHECK(tester.SourcePositionsMatch(
        optimization_bitmap, test_case_data.script(),
        test_case_data.declaration_parameters(), test_case_data.arguments()));
  }
}

#define MAKE_TEST(Name, Bitmap)               \
  TEST(TestSourcePositionsEquivalent##Name) { \
    TestSourcePositionsEquivalent(Bitmap);    \
  }
TEST_CASES(MAKE_TEST)
#undef MAKE_TEST

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