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