Line data Source code
1 : // 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 :
5 : #include "src/objects-inl.h"
6 : #include "test/cctest/compiler/function-tester.h"
7 :
8 : namespace v8 {
9 : namespace internal {
10 : namespace compiler {
11 :
12 28342 : TEST(Throw) {
13 5 : FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})");
14 :
15 10 : T.CheckThrows(T.true_value(), T.NewObject("new Error"));
16 5 : T.CheckCall(T.Val(23), T.false_value(), T.Val(23));
17 5 : }
18 :
19 :
20 28342 : TEST(ThrowMessagePosition) {
21 : static const char* src =
22 : "(function(a, b) { \n"
23 : " if (a == 1) throw 1; \n"
24 : " if (a == 2) {throw 2} \n"
25 : " if (a == 3) {0;throw 3}\n"
26 : " throw 4; \n"
27 : "}) ";
28 5 : FunctionTester T(src);
29 : v8::Local<v8::Message> message;
30 5 : v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
31 :
32 5 : message = T.CheckThrowsReturnMessage(T.Val(1), T.undefined());
33 10 : CHECK_EQ(2, message->GetLineNumber(context).FromMaybe(-1));
34 5 : CHECK_EQ(40, message->GetStartPosition());
35 :
36 5 : message = T.CheckThrowsReturnMessage(T.Val(2), T.undefined());
37 10 : CHECK_EQ(3, message->GetLineNumber(context).FromMaybe(-1));
38 5 : CHECK_EQ(67, message->GetStartPosition());
39 :
40 5 : message = T.CheckThrowsReturnMessage(T.Val(3), T.undefined());
41 10 : CHECK_EQ(4, message->GetLineNumber(context).FromMaybe(-1));
42 5 : CHECK_EQ(95, message->GetStartPosition());
43 5 : }
44 :
45 :
46 28342 : TEST(ThrowMessageDirectly) {
47 : static const char* src =
48 : "(function(a, b) {"
49 : " if (a) { throw b; } else { throw new Error(b); }"
50 : "})";
51 5 : FunctionTester T(src);
52 : v8::Local<v8::Message> message;
53 5 : v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
54 : v8::Maybe<bool> t = v8::Just(true);
55 :
56 10 : message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
57 20 : CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));
58 :
59 10 : message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
60 20 : CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
61 5 : }
62 :
63 :
64 28342 : TEST(ThrowMessageIndirectly) {
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 5 : FunctionTester T(src);
74 : v8::Local<v8::Message> message;
75 5 : v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
76 : v8::Maybe<bool> t = v8::Just(true);
77 :
78 10 : message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
79 20 : CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Error: Wat?")));
80 :
81 10 : message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
82 20 : CHECK(t == message->Get()->Equals(context, v8_str("Uncaught Kaboom!")));
83 5 : }
84 :
85 :
86 28342 : TEST(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 5 : FunctionTester T(src);
99 :
100 10 : T.CheckCall(T.Val("-A-B-"));
101 5 : }
102 :
103 :
104 28342 : TEST(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 5 : FunctionTester T(src);
122 :
123 10 : T.CheckCall(T.Val("-A-B-C-"));
124 5 : }
125 :
126 :
127 28342 : TEST(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 5 : FunctionTester T(src);
144 :
145 10 : T.CheckCall(T.Val("-A-D-"), T.true_value(), T.false_value());
146 10 : T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
147 10 : T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
148 5 : }
149 :
150 :
151 28342 : TEST(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 5 : FunctionTester T(src);
164 :
165 : CompileRun("function thrower() { throw 'T-'; }");
166 15 : T.CheckCall(T.Val("-A-T-"), T.NewFunction("thrower"));
167 : CompileRun("function returner() { return 'R-'; }");
168 15 : T.CheckCall(T.Val("-A-B-R-"), T.NewFunction("returner"));
169 5 : }
170 :
171 :
172 28342 : TEST(Finally) {
173 : const char* src =
174 : "(function(a,b) {"
175 : " var r = '-';"
176 : " try {"
177 : " r += 'A-';"
178 : " } finally {"
179 : " r += 'B-';"
180 : " }"
181 : " return r;"
182 : "})";
183 5 : FunctionTester T(src);
184 :
185 10 : T.CheckCall(T.Val("-A-B-"));
186 5 : }
187 :
188 :
189 28342 : TEST(FinallyBreak) {
190 : const char* src =
191 : "(function(a,b) {"
192 : " var r = '-';"
193 : " L: try {"
194 : " r += 'A-';"
195 : " if (a) return r;"
196 : " r += 'B-';"
197 : " if (b) break L;"
198 : " r += 'C-';"
199 : " } finally {"
200 : " r += 'D-';"
201 : " }"
202 : " return r;"
203 : "})";
204 5 : FunctionTester T(src);
205 :
206 10 : T.CheckCall(T.Val("-A-"), T.true_value(), T.false_value());
207 10 : T.CheckCall(T.Val("-A-B-D-"), T.false_value(), T.true_value());
208 10 : T.CheckCall(T.Val("-A-B-C-D-"), T.false_value(), T.false_value());
209 5 : }
210 :
211 :
212 28342 : TEST(DeoptTry) {
213 : const char* src =
214 : "(function f(a) {"
215 : " try {"
216 : " %DeoptimizeFunction(f);"
217 : " throw a;"
218 : " } catch (e) {"
219 : " return e + 1;"
220 : " }"
221 : "})";
222 5 : FunctionTester T(src);
223 :
224 5 : T.CheckCall(T.Val(2), T.Val(1));
225 5 : }
226 :
227 :
228 28342 : TEST(DeoptCatch) {
229 : const char* src =
230 : "(function f(a) {"
231 : " try {"
232 : " throw a;"
233 : " } catch (e) {"
234 : " %DeoptimizeFunction(f);"
235 : " return e + 1;"
236 : " }"
237 : "})";
238 5 : FunctionTester T(src);
239 :
240 5 : T.CheckCall(T.Val(2), T.Val(1));
241 5 : }
242 :
243 :
244 28342 : TEST(DeoptFinallyReturn) {
245 : const char* src =
246 : "(function f(a) {"
247 : " try {"
248 : " throw a;"
249 : " } finally {"
250 : " %DeoptimizeFunction(f);"
251 : " return a + 1;"
252 : " }"
253 : "})";
254 5 : FunctionTester T(src);
255 :
256 5 : T.CheckCall(T.Val(2), T.Val(1));
257 5 : }
258 :
259 :
260 28342 : TEST(DeoptFinallyReThrow) {
261 : const char* src =
262 : "(function f(a) {"
263 : " try {"
264 : " throw a;"
265 : " } finally {"
266 : " %DeoptimizeFunction(f);"
267 : " }"
268 : "})";
269 5 : FunctionTester T(src);
270 :
271 10 : T.CheckThrows(T.NewObject("new Error"), T.Val(1));
272 5 : }
273 :
274 : } // namespace compiler
275 : } // namespace internal
276 85011 : } // namespace v8
|