// 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 "src/objects/objects-inl.h"
#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
