blob: 37b2a2d243c430f5a91e56ed13b7ed14f4856484 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "test/cctest/compiler/function-tester.h"
6
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007namespace v8 {
8namespace internal {
9namespace compiler {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010
11TEST(Throw) {
12 FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})");
13
14 T.CheckThrows(T.true_value(), T.NewObject("new Error"));
15 T.CheckCall(T.Val(23), T.false_value(), T.Val(23));
16}
17
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019TEST(ThrowMessagePosition) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000020 static const char* src =
21 "(function(a, b) { \n"
22 " if (a == 1) throw 1; \n"
23 " if (a == 2) {throw 2} \n"
24 " if (a == 3) {0;throw 3}\n"
25 " throw 4; \n"
26 "}) ";
27 FunctionTester T(src);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000028 v8::Local<v8::Message> message;
29 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030
31 message = T.CheckThrowsReturnMessage(T.Val(1), T.undefined());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032 CHECK_EQ(2, message->GetLineNumber(context).FromMaybe(-1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033 CHECK_EQ(40, message->GetStartPosition());
34
35 message = T.CheckThrowsReturnMessage(T.Val(2), T.undefined());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036 CHECK_EQ(3, message->GetLineNumber(context).FromMaybe(-1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000037 CHECK_EQ(67, message->GetStartPosition());
38
39 message = T.CheckThrowsReturnMessage(T.Val(3), T.undefined());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 CHECK_EQ(4, message->GetLineNumber(context).FromMaybe(-1));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 CHECK_EQ(95, message->GetStartPosition());
42}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043
44
45TEST(ThrowMessageDirectly) {
46 static const char* src =
47 "(function(a, b) {"
48 " if (a) { throw b; } else { throw new Error(b); }"
49 "})";
50 FunctionTester T(src);
51 v8::Local<v8::Message> message;
52 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
53 v8::Maybe<bool> t = v8::Just(true);
54
55 message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
56 CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));
57
58 message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
59 CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
60}
61
62
63TEST(ThrowMessageIndirectly) {
64 i::FLAG_turbo_try_finally = true;
65 static const char* src =
66 "(function(a, b) {"
67 " try {"
68 " if (a) { throw b; } else { throw new Error(b); }"
69 " } finally {"
70 " try { throw 'clobber'; } catch (e) { 'unclobber'; }"
71 " }"
72 "})";
73 FunctionTester T(src);
74 v8::Local<v8::Message> message;
75 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
76 v8::Maybe<bool> t = v8::Just(true);
77
78 message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
79 CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));
80
81 message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
82 CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
83}
84
85
86TEST(Catch) {
87 const char* src =
88 "(function(a,b) {"
89 " var r = '-';"
90 " try {"
91 " r += 'A-';"
92 " throw 'B-';"
93 " } catch (e) {"
94 " r += e;"
95 " }"
96 " return r;"
97 "})";
98 FunctionTester T(src);
99
100 T.CheckCall(T.Val("-A-B-"));
101}
102
103
104TEST(CatchNested) {
105 const char* src =
106 "(function(a,b) {"
107 " var r = '-';"
108 " try {"
109 " r += 'A-';"
110 " throw 'C-';"
111 " } catch (e) {"
112 " try {"
113 " throw 'B-';"
114 " } catch (e) {"
115 " r += e;"
116 " }"
117 " r += e;"
118 " }"
119 " return r;"
120 "})";
121 FunctionTester T(src);
122
123 T.CheckCall(T.Val("-A-B-C-"));
124}
125
126
127TEST(CatchBreak) {
128 const char* src =
129 "(function(a,b) {"
130 " var r = '-';"
131 " L: try {"
132 " r += 'A-';"
133 " if (a) break L;"
134 " r += 'B-';"
135 " throw 'C-';"
136 " } catch (e) {"
137 " if (b) break L;"
138 " r += e;"
139 " }"
140 " r += 'D-';"
141 " return r;"
142 "})";
143 FunctionTester T(src);
144
145 T.CheckCall(T.Val("-A-D-"), T.true_value(), T.false_value());
146 T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
147 T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
148}
149
150
151TEST(CatchCall) {
152 const char* src =
153 "(function(fun) {"
154 " var r = '-';"
155 " try {"
156 " r += 'A-';"
157 " return r + 'B-' + fun();"
158 " } catch (e) {"
159 " r += e;"
160 " }"
161 " return r;"
162 "})";
163 FunctionTester T(src);
164
165 CompileRun("function thrower() { throw 'T-'; }");
166 T.CheckCall(T.Val("-A-T-"), T.NewFunction("thrower"));
167 CompileRun("function returner() { return 'R-'; }");
168 T.CheckCall(T.Val("-A-B-R-"), T.NewFunction("returner"));
169}
170
171
172TEST(Finally) {
173 i::FLAG_turbo_try_finally = true;
174 const char* src =
175 "(function(a,b) {"
176 " var r = '-';"
177 " try {"
178 " r += 'A-';"
179 " } finally {"
180 " r += 'B-';"
181 " }"
182 " return r;"
183 "})";
184 FunctionTester T(src);
185
186 T.CheckCall(T.Val("-A-B-"));
187}
188
189
190TEST(FinallyBreak) {
191 i::FLAG_turbo_try_finally = true;
192 const char* src =
193 "(function(a,b) {"
194 " var r = '-';"
195 " L: try {"
196 " r += 'A-';"
197 " if (a) return r;"
198 " r += 'B-';"
199 " if (b) break L;"
200 " r += 'C-';"
201 " } finally {"
202 " r += 'D-';"
203 " }"
204 " return r;"
205 "})";
206 FunctionTester T(src);
207
208 T.CheckCall(T.Val("-A-"), T.true_value(), T.false_value());
209 T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
210 T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
211}
212
213
214TEST(DeoptTry) {
215 const char* src =
216 "(function f(a) {"
217 " try {"
218 " %DeoptimizeFunction(f);"
219 " throw a;"
220 " } catch (e) {"
221 " return e + 1;"
222 " }"
223 "})";
224 FunctionTester T(src);
225
226 T.CheckCall(T.Val(2), T.Val(1));
227}
228
229
230TEST(DeoptCatch) {
231 const char* src =
232 "(function f(a) {"
233 " try {"
234 " throw a;"
235 " } catch (e) {"
236 " %DeoptimizeFunction(f);"
237 " return e + 1;"
238 " }"
239 "})";
240 FunctionTester T(src);
241
242 T.CheckCall(T.Val(2), T.Val(1));
243}
244
245
246TEST(DeoptFinallyReturn) {
247 i::FLAG_turbo_try_finally = true;
248 const char* src =
249 "(function f(a) {"
250 " try {"
251 " throw a;"
252 " } finally {"
253 " %DeoptimizeFunction(f);"
254 " return a + 1;"
255 " }"
256 "})";
257 FunctionTester T(src);
258
259 T.CheckCall(T.Val(2), T.Val(1));
260}
261
262
263TEST(DeoptFinallyReThrow) {
264 i::FLAG_turbo_try_finally = true;
265 const char* src =
266 "(function f(a) {"
267 " try {"
268 " throw a;"
269 " } finally {"
270 " %DeoptimizeFunction(f);"
271 " }"
272 "})";
273 FunctionTester T(src);
274
275#if 0 // TODO(mstarzinger): Enable once we can.
276 T.CheckThrows(T.NewObject("new Error"), T.Val(1));
277#endif
278}
279
280} // namespace compiler
281} // namespace internal
282} // namespace v8