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 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 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 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 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 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 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 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 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 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 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 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 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 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 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