// Copyright 2014 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 "test/cctest/compiler/function-tester.h"

namespace v8 {
namespace internal {
namespace compiler {

TEST(Throw) {
  FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})");

  T.CheckThrows(T.true_value(), T.NewObject("new Error"));
  T.CheckCall(T.Val(23), T.false_value(), T.Val(23));
}


TEST(ThrowMessagePosition) {
  static const char* src =
      "(function(a, b) {        \n"
      "  if (a == 1) throw 1;   \n"
      "  if (a == 2) {throw 2}  \n"
      "  if (a == 3) {0;throw 3}\n"
      "  throw 4;               \n"
      "})                       ";
  FunctionTester T(src);
  v8::Local<v8::Message> message;
  v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();

  message = T.CheckThrowsReturnMessage(T.Val(1), T.undefined());
  CHECK_EQ(2, message->GetLineNumber(context).FromMaybe(-1));
  CHECK_EQ(40, message->GetStartPosition());

  message = T.CheckThrowsReturnMessage(T.Val(2), T.undefined());
  CHECK_EQ(3, message->GetLineNumber(context).FromMaybe(-1));
  CHECK_EQ(67, message->GetStartPosition());

  message = T.CheckThrowsReturnMessage(T.Val(3), T.undefined());
  CHECK_EQ(4, message->GetLineNumber(context).FromMaybe(-1));
  CHECK_EQ(95, message->GetStartPosition());
}


TEST(ThrowMessageDirectly) {
  static const char* src =
      "(function(a, b) {"
      "  if (a) { throw b; } else { throw new Error(b); }"
      "})";
  FunctionTester T(src);
  v8::Local<v8::Message> message;
  v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
  v8::Maybe<bool> t = v8::Just(true);

  message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
  CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));

  message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
  CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
}


TEST(ThrowMessageIndirectly) {
  static const char* src =
      "(function(a, b) {"
      "  try {"
      "    if (a) { throw b; } else { throw new Error(b); }"
      "  } finally {"
      "    try { throw 'clobber'; } catch (e) { 'unclobber'; }"
      "  }"
      "})";
  FunctionTester T(src);
  v8::Local<v8::Message> message;
  v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
  v8::Maybe<bool> t = v8::Just(true);

  message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
  CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));

  message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
  CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
}


TEST(Catch) {
  const char* src =
      "(function(a,b) {"
      "  var r = '-';"
      "  try {"
      "    r += 'A-';"
      "    throw 'B-';"
      "  } catch (e) {"
      "    r += e;"
      "  }"
      "  return r;"
      "})";
  FunctionTester T(src);

  T.CheckCall(T.Val("-A-B-"));
}


TEST(CatchNested) {
  const char* src =
      "(function(a,b) {"
      "  var r = '-';"
      "  try {"
      "    r += 'A-';"
      "    throw 'C-';"
      "  } catch (e) {"
      "    try {"
      "      throw 'B-';"
      "    } catch (e) {"
      "      r += e;"
      "    }"
      "    r += e;"
      "  }"
      "  return r;"
      "})";
  FunctionTester T(src);

  T.CheckCall(T.Val("-A-B-C-"));
}


TEST(CatchBreak) {
  const char* src =
      "(function(a,b) {"
      "  var r = '-';"
      "  L: try {"
      "    r += 'A-';"
      "    if (a) break L;"
      "    r += 'B-';"
      "    throw 'C-';"
      "  } catch (e) {"
      "    if (b) break L;"
      "    r += e;"
      "  }"
      "  r += 'D-';"
      "  return r;"
      "})";
  FunctionTester T(src);

  T.CheckCall(T.Val("-A-D-"), T.true_value(), T.false_value());
  T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
  T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
}


TEST(CatchCall) {
  const char* src =
      "(function(fun) {"
      "  var r = '-';"
      "  try {"
      "    r += 'A-';"
      "    return r + 'B-' + fun();"
      "  } catch (e) {"
      "    r += e;"
      "  }"
      "  return r;"
      "})";
  FunctionTester T(src);

  CompileRun("function thrower() { throw 'T-'; }");
  T.CheckCall(T.Val("-A-T-"), T.NewFunction("thrower"));
  CompileRun("function returner() { return 'R-'; }");
  T.CheckCall(T.Val("-A-B-R-"), T.NewFunction("returner"));
}


TEST(Finally) {
  const char* src =
      "(function(a,b) {"
      "  var r = '-';"
      "  try {"
      "    r += 'A-';"
      "  } finally {"
      "    r += 'B-';"
      "  }"
      "  return r;"
      "})";
  FunctionTester T(src);

  T.CheckCall(T.Val("-A-B-"));
}


TEST(FinallyBreak) {
  const char* src =
      "(function(a,b) {"
      "  var r = '-';"
      "  L: try {"
      "    r += 'A-';"
      "    if (a) return r;"
      "    r += 'B-';"
      "    if (b) break L;"
      "    r += 'C-';"
      "  } finally {"
      "    r += 'D-';"
      "  }"
      "  return r;"
      "})";
  FunctionTester T(src);

  T.CheckCall(T.Val("-A-"), T.true_value(), T.false_value());
  T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
  T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
}


TEST(DeoptTry) {
  const char* src =
      "(function f(a) {"
      "  try {"
      "    %DeoptimizeFunction(f);"
      "    throw a;"
      "  } catch (e) {"
      "    return e + 1;"
      "  }"
      "})";
  FunctionTester T(src);

  T.CheckCall(T.Val(2), T.Val(1));
}


TEST(DeoptCatch) {
  const char* src =
      "(function f(a) {"
      "  try {"
      "    throw a;"
      "  } catch (e) {"
      "    %DeoptimizeFunction(f);"
      "    return e + 1;"
      "  }"
      "})";
  FunctionTester T(src);

  T.CheckCall(T.Val(2), T.Val(1));
}


TEST(DeoptFinallyReturn) {
  const char* src =
      "(function f(a) {"
      "  try {"
      "    throw a;"
      "  } finally {"
      "    %DeoptimizeFunction(f);"
      "    return a + 1;"
      "  }"
      "})";
  FunctionTester T(src);

  T.CheckCall(T.Val(2), T.Val(1));
}


TEST(DeoptFinallyReThrow) {
  const char* src =
      "(function f(a) {"
      "  try {"
      "    throw a;"
      "  } finally {"
      "    %DeoptimizeFunction(f);"
      "  }"
      "})";
  FunctionTester T(src);

  T.CheckThrows(T.NewObject("new Error"), T.Val(1));
}

}  // namespace compiler
}  // namespace internal
}  // namespace v8
