8e7241fdde
Rebuilding (after touching certain files) is crazy slow because includes are out of control. Many of these files we need to rebuild are cctests which pull in more includes than they need. BUG=v8:5294 Review-Url: https://codereview.chromium.org/2304553002 Cr-Commit-Position: refs/heads/master@{#39080}
277 lines
6.4 KiB
C++
277 lines
6.4 KiB
C++
// 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-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
|