OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 <stdint.h> |
| 6 #include <stdlib.h> |
| 7 #include <string.h> |
| 8 |
| 9 #include "src/base/platform/elapsed-timer.h" |
| 10 |
| 11 #include "src/wasm/wasm-macro-gen.h" |
| 12 |
| 13 #include "test/cctest/cctest.h" |
| 14 #include "test/cctest/compiler/value-helper.h" |
| 15 #include "test/cctest/wasm/test-signatures.h" |
| 16 #include "test/cctest/wasm/wasm-run-utils.h" |
| 17 |
| 18 using namespace v8::base; |
| 19 using namespace v8::internal; |
| 20 using namespace v8::internal::compiler; |
| 21 using namespace v8::internal::wasm; |
| 22 |
| 23 // TODO(jpp): WASM_EXEC_TEST(TryCatch) |
| 24 |
| 25 // TODO(jpp): Move these macros to src/wasm/wasm-macro-gen.h once zero cost |
| 26 // exceptions are added to the spec. |
| 27 #define WASM_TRY_FINALLY(...) kExprTryFinally, __VA_ARGS__, kExprEnd |
| 28 #define WASM_FINALLY(...) kExprFinally, __VA_ARGS__ |
| 29 |
| 30 WASM_EXEC_TEST(TryFinally_single) { |
| 31 if (execution_mode == kExecuteInterpreted) { |
| 32 // TODO(jpp): implement eh support in the interpreter. |
| 33 return; |
| 34 } |
| 35 |
| 36 FLAG_wasm_eh_prototype = true; |
| 37 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
| 38 MachineType::Int32()); |
| 39 // r(i32 p, i32 q) -> i32 { |
| 40 // try { |
| 41 // if (q) { |
| 42 // break; |
| 43 // } |
| 44 // p += 0x0f0; |
| 45 // } finally { |
| 46 // p += 0x00f; |
| 47 // } |
| 48 // p += 0xf00 |
| 49 // return p; |
| 50 // } |
| 51 BUILD(r, WASM_TRY_FINALLY( |
| 52 WASM_IF(WASM_GET_LOCAL(1), WASM_BREAK(0)), |
| 53 WASM_SET_LOCAL( |
| 54 0, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V_2(0xf0))), |
| 55 WASM_FINALLY(WASM_SET_LOCAL( |
| 56 0, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V_1(0x0f))))), |
| 57 WASM_SET_LOCAL(0, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V(0xf00))), |
| 58 WASM_GET_LOCAL(0)); |
| 59 |
| 60 CHECK_EQ(0xFFFF, r.Call(0xF000, 0)); |
| 61 CHECK_EQ(0xFF0F, r.Call(0xF000, 1)); |
| 62 } |
| 63 |
| 64 WASM_EXEC_TEST(TryFinally_double) { |
| 65 if (execution_mode == kExecuteInterpreted) { |
| 66 // TODO(jpp): implement eh support in the interpreter. |
| 67 return; |
| 68 } |
| 69 |
| 70 FLAG_wasm_eh_prototype = true; |
| 71 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
| 72 MachineType::Int32()); |
| 73 // r(i32 p, i32 q) -> i32 { |
| 74 // a: try { |
| 75 // b: try { |
| 76 // if (q == 40) { |
| 77 // break a; |
| 78 // } else { |
| 79 // if (q == 1) { |
| 80 // break b; |
| 81 // } |
| 82 // } |
| 83 // p += 0x00000f; |
| 84 // } finally { |
| 85 // p += 0x0000f0; |
| 86 // } |
| 87 // p += 0x000f00; |
| 88 // } finally { |
| 89 // p += 0x00f000; |
| 90 // } |
| 91 // return p; |
| 92 // } |
| 93 BUILD( |
| 94 r, |
| 95 WASM_TRY_FINALLY( |
| 96 WASM_TRY_FINALLY( |
| 97 WASM_IF_ELSE(WASM_I32_EQ(WASM_GET_LOCAL(1), WASM_I32V(40)), |
| 98 WASM_BREAK(1), |
| 99 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(1), WASM_I32V(1)), |
| 100 WASM_BREAK(1))), |
| 101 WASM_SET_LOCAL( |
| 102 0, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V(0x00000f))), |
| 103 WASM_FINALLY(WASM_SET_LOCAL( |
| 104 0, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V(0x0000f0))))), |
| 105 WASM_SET_LOCAL(0, |
| 106 WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V(0x000f00))), |
| 107 WASM_FINALLY(WASM_SET_LOCAL( |
| 108 0, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_I32V(0x00f000))))), |
| 109 WASM_GET_LOCAL(0)); |
| 110 |
| 111 CHECK_EQ(0x7000ffff, r.Call(0x70000000, 2)); |
| 112 CHECK_EQ(0x7000fff0, r.Call(0x70000000, 1)); |
| 113 CHECK_EQ(0x7000f0f0, r.Call(0x70000000, 40)); |
| 114 } |
| 115 |
| 116 WASM_EXEC_TEST(TryFinally_multiple) { |
| 117 if (execution_mode == kExecuteInterpreted) { |
| 118 // TODO(jpp): implement eh support in the interpreter. |
| 119 return; |
| 120 } |
| 121 |
| 122 FLAG_wasm_eh_prototype = true; |
| 123 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
| 124 MachineType::Int32()); |
| 125 |
| 126 // Handy-dandy shortcuts for recurring patterns for this test. |
| 127 #define I32_IOR_LOCAL(local, value) \ |
| 128 WASM_SET_LOCAL(local, WASM_I32_IOR(WASM_GET_LOCAL(local), WASM_I32V(value))) |
| 129 #define IF_LOCAL_IS_BREAK_TO(local, value, depth) \ |
| 130 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(local), WASM_I32V(value)), \ |
| 131 WASM_BREAK(depth)) |
| 132 |
| 133 // r(i32 p, i32 q) -> i32 { |
| 134 // a: try { |
| 135 // b: try { |
| 136 // c: try { |
| 137 // d: try { |
| 138 // e: try { |
| 139 // switch (q) { |
| 140 // case 1: break e; |
| 141 // case 2: break d; |
| 142 // case 3: break c; |
| 143 // case 4: break b; |
| 144 // case 5: break a; |
| 145 // } |
| 146 // p |= 0x00000001; |
| 147 // } finally { |
| 148 // p |= 0x00000002; |
| 149 // } |
| 150 // switch (q) { |
| 151 // case 6: break d; |
| 152 // case 7: break c; |
| 153 // case 8: break b; |
| 154 // case 9: break a; |
| 155 // } |
| 156 // p |= 0x00000004; |
| 157 // } finally { |
| 158 // p |= 0x00000008; |
| 159 // } |
| 160 // switch (q) { |
| 161 // case 10: break c; |
| 162 // case 11: break b; |
| 163 // case 12: break a; |
| 164 // } |
| 165 // p |= 0x00000010; |
| 166 // } finally { |
| 167 // p |= 0x00000020; |
| 168 // } |
| 169 // switch (q) { |
| 170 // case 13: break b; |
| 171 // case 14: break a; |
| 172 // } |
| 173 // p |= 0x00000040; |
| 174 // } finally { |
| 175 // p |= 0x00000080; |
| 176 // } |
| 177 // switch (q) { |
| 178 // case 15: break a; |
| 179 // } |
| 180 // p |= 0x00000100; |
| 181 // } finally { |
| 182 // p |= 0x00000200; |
| 183 // } |
| 184 // return p; |
| 185 // } |
| 186 BUILD( |
| 187 r, |
| 188 WASM_TRY_FINALLY( |
| 189 WASM_TRY_FINALLY( |
| 190 WASM_TRY_FINALLY( |
| 191 WASM_TRY_FINALLY( |
| 192 WASM_TRY_FINALLY( |
| 193 IF_LOCAL_IS_BREAK_TO(1, 1, 0), |
| 194 IF_LOCAL_IS_BREAK_TO(1, 2, 1), |
| 195 IF_LOCAL_IS_BREAK_TO(1, 3, 2), |
| 196 IF_LOCAL_IS_BREAK_TO(1, 4, 3), |
| 197 IF_LOCAL_IS_BREAK_TO(1, 5, 4), |
| 198 I32_IOR_LOCAL(0, 0x00000001), |
| 199 WASM_FINALLY(I32_IOR_LOCAL(0, 0x00000002))), |
| 200 IF_LOCAL_IS_BREAK_TO(1, 6, 0), |
| 201 IF_LOCAL_IS_BREAK_TO(1, 7, 1), |
| 202 IF_LOCAL_IS_BREAK_TO(1, 8, 2), |
| 203 IF_LOCAL_IS_BREAK_TO(1, 9, 3), |
| 204 I32_IOR_LOCAL(0, 0x00000004), |
| 205 WASM_FINALLY(I32_IOR_LOCAL(0, 0x00000008))), |
| 206 IF_LOCAL_IS_BREAK_TO(1, 10, 0), |
| 207 IF_LOCAL_IS_BREAK_TO(1, 11, 1), |
| 208 IF_LOCAL_IS_BREAK_TO(1, 12, 2), I32_IOR_LOCAL(0, 0x00000010), |
| 209 WASM_FINALLY(I32_IOR_LOCAL(0, 0x00000020))), |
| 210 IF_LOCAL_IS_BREAK_TO(1, 13, 0), IF_LOCAL_IS_BREAK_TO(1, 14, 1), |
| 211 I32_IOR_LOCAL(0, 0x00000040), |
| 212 WASM_FINALLY(I32_IOR_LOCAL(0, 0x00000080))), |
| 213 IF_LOCAL_IS_BREAK_TO(1, 15, 0), I32_IOR_LOCAL(0, 0x00000100), |
| 214 WASM_FINALLY(I32_IOR_LOCAL(0, 0x00000200))), |
| 215 WASM_GET_LOCAL(0)); |
| 216 #undef WASM_IF_LOCAL_IS_BREAK_TO |
| 217 #undef WASM_I32_IOR_LOCAL |
| 218 |
| 219 const struct { |
| 220 uint32_t inputs[2]; |
| 221 uint32_t expected_output; |
| 222 } kTests[] = { |
| 223 {{0x80000000u, 0}, 0x800003ffu}, {{0x80000000u, 1}, 0x800003feu}, |
| 224 {{0x80000000u, 2}, 0x800003fau}, {{0x80000000u, 3}, 0x800003eau}, |
| 225 {{0x80000000u, 4}, 0x800003aau}, {{0x80000000u, 5}, 0x800002aau}, |
| 226 {{0x80000000u, 6}, 0x800003fbu}, {{0x80000000u, 7}, 0x800003ebu}, |
| 227 {{0x80000000u, 8}, 0x800003abu}, {{0x80000000u, 9}, 0x800002abu}, |
| 228 {{0x80000000u, 10}, 0x800003efu}, {{0x80000000u, 11}, 0x800003afu}, |
| 229 {{0x80000000u, 12}, 0x800002afu}, {{0x80000000u, 13}, 0x800003bfu}, |
| 230 {{0x80000000u, 14}, 0x800002bfu}, {{0x80000000u, 15}, 0x800002ffu}, |
| 231 }; |
| 232 |
| 233 for (uint32_t ii = 0; ii < arraysize(kTests); ++ii) { |
| 234 const auto& test_instance = kTests[ii]; |
| 235 CHECK_EQ(test_instance.expected_output, |
| 236 static_cast<uint32_t>( |
| 237 r.Call(test_instance.inputs[0], test_instance.inputs[1]))); |
| 238 } |
| 239 } |
| 240 |
| 241 WASM_EXEC_TEST(TryFinally_break_within_finally) { |
| 242 if (execution_mode == kExecuteInterpreted) { |
| 243 // TODO(jpp): implement eh support in the interpreter. |
| 244 return; |
| 245 } |
| 246 |
| 247 FLAG_wasm_eh_prototype = true; |
| 248 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
| 249 MachineType::Int32()); |
| 250 |
| 251 #define I32_IOR_LOCAL(local, value) \ |
| 252 WASM_SET_LOCAL(local, WASM_I32_IOR(WASM_GET_LOCAL(local), WASM_I32V(value))) |
| 253 #define IF_LOCAL_IS_BREAK_TO(local, value, depth) \ |
| 254 WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(local), WASM_I32V(value)), \ |
| 255 WASM_BREAK(depth)) |
| 256 |
| 257 // r(i32 p, i32 q) -> i32 { |
| 258 // a: try { |
| 259 // } finally { |
| 260 // b: try { |
| 261 // c: try { |
| 262 // } finally { |
| 263 // d: try { |
| 264 // e: try { |
| 265 // } finally { |
| 266 // f: try { |
| 267 // } finally { |
| 268 // if (q == 1) { |
| 269 // break a; |
| 270 // } |
| 271 // p |= 0x00000001 |
| 272 // } |
| 273 // p |= 0x00000002 |
| 274 // } |
| 275 // p |= 0x00000004 |
| 276 // } finally { |
| 277 // p |= 0x00000008 /* should run */ |
| 278 // } |
| 279 // p |= 0x00000010 |
| 280 // } |
| 281 // p |= 0x00000020 |
| 282 // } finally { |
| 283 // p |= 0x00000040 /* should run */ |
| 284 // } |
| 285 // p |= 0x00000080 |
| 286 // } |
| 287 // return p; |
| 288 // } |
| 289 BUILD(r, |
| 290 WASM_TRY_FINALLY( // a |
| 291 WASM_FINALLY( |
| 292 WASM_TRY_FINALLY( // b |
| 293 WASM_TRY_FINALLY( // c |
| 294 WASM_FINALLY( |
| 295 WASM_TRY_FINALLY( // d |
| 296 WASM_TRY_FINALLY( // e |
| 297 WASM_FINALLY( |
| 298 WASM_TRY_FINALLY( // f |
| 299 WASM_FINALLY( |
| 300 IF_LOCAL_IS_BREAK_TO(1, 1, 5), |
| 301 I32_IOR_LOCAL(0, 0x00000001))), |
| 302 I32_IOR_LOCAL(0, 0x00000002))), |
| 303 I32_IOR_LOCAL(0, 0x00000004), |
| 304 WASM_FINALLY(I32_IOR_LOCAL(0, 0x00000008))), |
| 305 I32_IOR_LOCAL(0, 0x00000010))), |
| 306 I32_IOR_LOCAL(0, 0x00000020), |
| 307 WASM_FINALLY(I32_IOR_LOCAL(0, 0x00000040))), |
| 308 I32_IOR_LOCAL(0, 0x00000080))), |
| 309 WASM_GET_LOCAL(0)); |
| 310 |
| 311 #undef WASM_IF_LOCAL_IS_BREAK_TO |
| 312 #undef WASM_I32_IOR_LOCAL |
| 313 |
| 314 CHECK_EQ(0x40000048, r.Call(0x40000000, 1)); |
| 315 } |
| 316 |
| 317 // TODO(jpp): WASM_EXEC_TEST(TryCatchFinally) |
OLD | NEW |