• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "test/cctest/compiler/function-tester.h"
6 
7 namespace v8 {
8 namespace internal {
9 namespace compiler {
10 
TEST(Throw)11 TEST(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 
TEST(ThrowMessagePosition)19 TEST(ThrowMessagePosition) {
20   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);
28   v8::Local<v8::Message> message;
29   v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
30 
31   message = T.CheckThrowsReturnMessage(T.Val(1), T.undefined());
32   CHECK_EQ(2, message->GetLineNumber(context).FromMaybe(-1));
33   CHECK_EQ(40, message->GetStartPosition());
34 
35   message = T.CheckThrowsReturnMessage(T.Val(2), T.undefined());
36   CHECK_EQ(3, message->GetLineNumber(context).FromMaybe(-1));
37   CHECK_EQ(67, message->GetStartPosition());
38 
39   message = T.CheckThrowsReturnMessage(T.Val(3), T.undefined());
40   CHECK_EQ(4, message->GetLineNumber(context).FromMaybe(-1));
41   CHECK_EQ(95, message->GetStartPosition());
42 }
43 
44 
TEST(ThrowMessageDirectly)45 TEST(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 
TEST(ThrowMessageIndirectly)63 TEST(ThrowMessageIndirectly) {
64   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 
TEST(Catch)85 TEST(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 
TEST(CatchNested)103 TEST(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 
TEST(CatchBreak)126 TEST(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 
TEST(CatchCall)150 TEST(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 
TEST(Finally)171 TEST(Finally) {
172   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 
TEST(FinallyBreak)188 TEST(FinallyBreak) {
189   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 
TEST(DeoptTry)211 TEST(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 
TEST(DeoptCatch)227 TEST(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 
TEST(DeoptFinallyReturn)243 TEST(DeoptFinallyReturn) {
244   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 
TEST(DeoptFinallyReThrow)259 TEST(DeoptFinallyReThrow) {
260   const char* src =
261       "(function f(a) {"
262       "  try {"
263       "    throw a;"
264       "  } finally {"
265       "    %DeoptimizeFunction(f);"
266       "  }"
267       "})";
268   FunctionTester T(src);
269 
270   T.CheckThrows(T.NewObject("new Error"), T.Val(1));
271 }
272 
273 }  // namespace compiler
274 }  // namespace internal
275 }  // namespace v8
276