blob: ab8c42a9796b7d472a58d7c0c20beddbeab2ca3c [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) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 static const char* src =
65 "(function(a, b) {"
66 " try {"
67 " if (a) { throw b; } else { throw new Error(b); }"
68 " } finally {"
69 " try { throw 'clobber'; } catch (e) { 'unclobber'; }"
70 " }"
71 "})";
72 FunctionTester T(src);
73 v8::Local<v8::Message> message;
74 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
75 v8::Maybe<bool> t = v8::Just(true);
76
77 message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
78 CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));
79
80 message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
81 CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
82}
83
84
85TEST(Catch) {
86 const char* src =
87 "(function(a,b) {"
88 " var r = '-';"
89 " try {"
90 " r += 'A-';"
91 " throw 'B-';"
92 " } catch (e) {"
93 " r += e;"
94 " }"
95 " return r;"
96 "})";
97 FunctionTester T(src);
98
99 T.CheckCall(T.Val("-A-B-"));
100}
101
102
103TEST(CatchNested) {
104 const char* src =
105 "(function(a,b) {"
106 " var r = '-';"
107 " try {"
108 " r += 'A-';"
109 " throw 'C-';"
110 " } catch (e) {"
111 " try {"
112 " throw 'B-';"
113 " } catch (e) {"
114 " r += e;"
115 " }"
116 " r += e;"
117 " }"
118 " return r;"
119 "})";
120 FunctionTester T(src);
121
122 T.CheckCall(T.Val("-A-B-C-"));
123}
124
125
126TEST(CatchBreak) {
127 const char* src =
128 "(function(a,b) {"
129 " var r = '-';"
130 " L: try {"
131 " r += 'A-';"
132 " if (a) break L;"
133 " r += 'B-';"
134 " throw 'C-';"
135 " } catch (e) {"
136 " if (b) break L;"
137 " r += e;"
138 " }"
139 " r += 'D-';"
140 " return r;"
141 "})";
142 FunctionTester T(src);
143
144 T.CheckCall(T.Val("-A-D-"), T.true_value(), T.false_value());
145 T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
146 T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
147}
148
149
150TEST(CatchCall) {
151 const char* src =
152 "(function(fun) {"
153 " var r = '-';"
154 " try {"
155 " r += 'A-';"
156 " return r + 'B-' + fun();"
157 " } catch (e) {"
158 " r += e;"
159 " }"
160 " return r;"
161 "})";
162 FunctionTester T(src);
163
164 CompileRun("function thrower() { throw 'T-'; }");
165 T.CheckCall(T.Val("-A-T-"), T.NewFunction("thrower"));
166 CompileRun("function returner() { return 'R-'; }");
167 T.CheckCall(T.Val("-A-B-R-"), T.NewFunction("returner"));
168}
169
170
171TEST(Finally) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172 const char* src =
173 "(function(a,b) {"
174 " var r = '-';"
175 " try {"
176 " r += 'A-';"
177 " } finally {"
178 " r += 'B-';"
179 " }"
180 " return r;"
181 "})";
182 FunctionTester T(src);
183
184 T.CheckCall(T.Val("-A-B-"));
185}
186
187
188TEST(FinallyBreak) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000189 const char* src =
190 "(function(a,b) {"
191 " var r = '-';"
192 " L: try {"
193 " r += 'A-';"
194 " if (a) return r;"
195 " r += 'B-';"
196 " if (b) break L;"
197 " r += 'C-';"
198 " } finally {"
199 " r += 'D-';"
200 " }"
201 " return r;"
202 "})";
203 FunctionTester T(src);
204
205 T.CheckCall(T.Val("-A-"), T.true_value(), T.false_value());
206 T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
207 T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
208}
209
210
211TEST(DeoptTry) {
212 const char* src =
213 "(function f(a) {"
214 " try {"
215 " %DeoptimizeFunction(f);"
216 " throw a;"
217 " } catch (e) {"
218 " return e + 1;"
219 " }"
220 "})";
221 FunctionTester T(src);
222
223 T.CheckCall(T.Val(2), T.Val(1));
224}
225
226
227TEST(DeoptCatch) {
228 const char* src =
229 "(function f(a) {"
230 " try {"
231 " throw a;"
232 " } catch (e) {"
233 " %DeoptimizeFunction(f);"
234 " return e + 1;"
235 " }"
236 "})";
237 FunctionTester T(src);
238
239 T.CheckCall(T.Val(2), T.Val(1));
240}
241
242
243TEST(DeoptFinallyReturn) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000244 const char* src =
245 "(function f(a) {"
246 " try {"
247 " throw a;"
248 " } finally {"
249 " %DeoptimizeFunction(f);"
250 " return a + 1;"
251 " }"
252 "})";
253 FunctionTester T(src);
254
255 T.CheckCall(T.Val(2), T.Val(1));
256}
257
258
259TEST(DeoptFinallyReThrow) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000260 const char* src =
261 "(function f(a) {"
262 " try {"
263 " throw a;"
264 " } finally {"
265 " %DeoptimizeFunction(f);"
266 " }"
267 "})";
268 FunctionTester T(src);
269
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000270 T.CheckThrows(T.NewObject("new Error"), T.Val(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000271}
272
273} // namespace compiler
274} // namespace internal
275} // namespace v8