| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 <stdint.h> | 5 #include <stdint.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 TEST(Run_WasmInt8Const_i) { | 29 TEST(Run_WasmInt8Const_i) { |
| 30 WasmRunner<int32_t> r(kExecuteInterpreted); | 30 WasmRunner<int32_t> r(kExecuteInterpreted); |
| 31 const byte kExpectedValue = 109; | 31 const byte kExpectedValue = 109; |
| 32 // return(kExpectedValue) | 32 // return(kExpectedValue) |
| 33 BUILD(r, WASM_I8(kExpectedValue)); | 33 BUILD(r, WASM_I8(kExpectedValue)); |
| 34 CHECK_EQ(kExpectedValue, r.Call()); | 34 CHECK_EQ(kExpectedValue, r.Call()); |
| 35 } | 35 } |
| 36 | 36 |
| 37 TEST(Run_WasmIfElse) { | 37 TEST(Run_WasmIfElse) { |
| 38 WasmRunner<int32_t, int32_t> r(kExecuteInterpreted); | 38 WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Int32()); |
| 39 BUILD(r, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I8(9), WASM_I8(10))); | 39 BUILD(r, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I8(9), WASM_I8(10))); |
| 40 CHECK_EQ(10, r.Call(0)); | 40 CHECK_EQ(10, r.Call(0)); |
| 41 CHECK_EQ(9, r.Call(1)); | 41 CHECK_EQ(9, r.Call(1)); |
| 42 } | 42 } |
| 43 | 43 |
| 44 TEST(Run_WasmIfReturn) { | 44 TEST(Run_WasmIfReturn) { |
| 45 WasmRunner<int32_t, int32_t> r(kExecuteInterpreted); | 45 WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Int32()); |
| 46 BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_RETURN1(WASM_I8(77))), WASM_I8(65)); | 46 BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_RETURN1(WASM_I8(77))), WASM_I8(65)); |
| 47 CHECK_EQ(65, r.Call(0)); | 47 CHECK_EQ(65, r.Call(0)); |
| 48 CHECK_EQ(77, r.Call(1)); | 48 CHECK_EQ(77, r.Call(1)); |
| 49 } | 49 } |
| 50 | 50 |
| 51 TEST(Run_WasmNopsN) { | 51 TEST(Run_WasmNopsN) { |
| 52 const int kMaxNops = 10; | 52 const int kMaxNops = 10; |
| 53 byte code[kMaxNops + 2]; | 53 byte code[kMaxNops + 2]; |
| 54 for (int nops = 0; nops < kMaxNops; nops++) { | 54 for (int nops = 0; nops < kMaxNops; nops++) { |
| 55 byte expected = static_cast<byte>(20 + nops); | 55 byte expected = static_cast<byte>(20 + nops); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 code[2 + index + 3] = 0; | 124 code[2 + index + 3] = 0; |
| 125 | 125 |
| 126 WasmRunner<int32_t> r(kExecuteInterpreted); | 126 WasmRunner<int32_t> r(kExecuteInterpreted); |
| 127 r.Build(code, code + kMaxNops + kExtra); | 127 r.Build(code, code + kMaxNops + kExtra); |
| 128 CHECK_EQ(expected, r.Call()); | 128 CHECK_EQ(expected, r.Call()); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 } | 131 } |
| 132 | 132 |
| 133 TEST(Run_Wasm_nested_ifs_i) { | 133 TEST(Run_Wasm_nested_ifs_i) { |
| 134 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteInterpreted); | 134 WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Int32(), |
| 135 MachineType::Int32()); |
| 135 | 136 |
| 136 BUILD(r, WASM_IF_ELSE_I( | 137 BUILD(r, WASM_IF_ELSE_I( |
| 137 WASM_GET_LOCAL(0), | 138 WASM_GET_LOCAL(0), |
| 138 WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)), | 139 WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)), |
| 139 WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14)))); | 140 WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14)))); |
| 140 | 141 |
| 141 CHECK_EQ(11, r.Call(1, 1)); | 142 CHECK_EQ(11, r.Call(1, 1)); |
| 142 CHECK_EQ(12, r.Call(1, 0)); | 143 CHECK_EQ(12, r.Call(1, 0)); |
| 143 CHECK_EQ(13, r.Call(0, 1)); | 144 CHECK_EQ(13, r.Call(0, 1)); |
| 144 CHECK_EQ(14, r.Call(0, 0)); | 145 CHECK_EQ(14, r.Call(0, 0)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 172 } | 173 } |
| 173 | 174 |
| 174 TEST(Breakpoint_I32Add) { | 175 TEST(Breakpoint_I32Add) { |
| 175 static const int kLocalsDeclSize = 1; | 176 static const int kLocalsDeclSize = 1; |
| 176 static const int kNumBreakpoints = 3; | 177 static const int kNumBreakpoints = 3; |
| 177 byte code[] = {WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; | 178 byte code[] = {WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; |
| 178 std::unique_ptr<int[]> offsets = | 179 std::unique_ptr<int[]> offsets = |
| 179 Find(code, sizeof(code), kNumBreakpoints, kExprGetLocal, kExprGetLocal, | 180 Find(code, sizeof(code), kNumBreakpoints, kExprGetLocal, kExprGetLocal, |
| 180 kExprI32Add); | 181 kExprI32Add); |
| 181 | 182 |
| 182 WasmRunner<int32_t, uint32_t, uint32_t> r(kExecuteInterpreted); | 183 WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Uint32(), |
| 184 MachineType::Uint32()); |
| 183 | 185 |
| 184 r.Build(code, code + arraysize(code)); | 186 r.Build(code, code + arraysize(code)); |
| 185 | 187 |
| 186 WasmInterpreter* interpreter = r.interpreter(); | 188 WasmInterpreter* interpreter = r.interpreter(); |
| 187 WasmInterpreter::Thread* thread = interpreter->GetThread(0); | 189 WasmInterpreter::Thread* thread = interpreter->GetThread(0); |
| 188 for (int i = 0; i < kNumBreakpoints; i++) { | 190 for (int i = 0; i < kNumBreakpoints; i++) { |
| 189 interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[i], | 191 interpreter->SetBreakpoint(r.function(), kLocalsDeclSize + offsets[i], |
| 190 true); | 192 true); |
| 191 } | 193 } |
| 192 | 194 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 211 uint32_t expected = (*a) + (b); | 213 uint32_t expected = (*a) + (b); |
| 212 CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>()); | 214 CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>()); |
| 213 } | 215 } |
| 214 } | 216 } |
| 215 } | 217 } |
| 216 | 218 |
| 217 TEST(Step_I32Mul) { | 219 TEST(Step_I32Mul) { |
| 218 static const int kTraceLength = 4; | 220 static const int kTraceLength = 4; |
| 219 byte code[] = {WASM_I32_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; | 221 byte code[] = {WASM_I32_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; |
| 220 | 222 |
| 221 WasmRunner<int32_t, uint32_t, uint32_t> r(kExecuteInterpreted); | 223 WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Uint32(), |
| 224 MachineType::Uint32()); |
| 222 | 225 |
| 223 r.Build(code, code + arraysize(code)); | 226 r.Build(code, code + arraysize(code)); |
| 224 | 227 |
| 225 WasmInterpreter* interpreter = r.interpreter(); | 228 WasmInterpreter* interpreter = r.interpreter(); |
| 226 WasmInterpreter::Thread* thread = interpreter->GetThread(0); | 229 WasmInterpreter::Thread* thread = interpreter->GetThread(0); |
| 227 | 230 |
| 228 FOR_UINT32_INPUTS(a) { | 231 FOR_UINT32_INPUTS(a) { |
| 229 for (uint32_t b = 33; b < 3000000000u; b += 1000000000u) { | 232 for (uint32_t b = 33; b < 3000000000u; b += 1000000000u) { |
| 230 thread->Reset(); | 233 thread->Reset(); |
| 231 WasmVal args[] = {WasmVal(*a), WasmVal(b)}; | 234 WasmVal args[] = {WasmVal(*a), WasmVal(b)}; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 249 } | 252 } |
| 250 } | 253 } |
| 251 | 254 |
| 252 TEST(Breakpoint_I32And_disable) { | 255 TEST(Breakpoint_I32And_disable) { |
| 253 static const int kLocalsDeclSize = 1; | 256 static const int kLocalsDeclSize = 1; |
| 254 static const int kNumBreakpoints = 1; | 257 static const int kNumBreakpoints = 1; |
| 255 byte code[] = {WASM_I32_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; | 258 byte code[] = {WASM_I32_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; |
| 256 std::unique_ptr<int[]> offsets = | 259 std::unique_ptr<int[]> offsets = |
| 257 Find(code, sizeof(code), kNumBreakpoints, kExprI32And); | 260 Find(code, sizeof(code), kNumBreakpoints, kExprI32And); |
| 258 | 261 |
| 259 WasmRunner<int32_t, uint32_t, uint32_t> r(kExecuteInterpreted); | 262 WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Uint32(), |
| 263 MachineType::Uint32()); |
| 260 | 264 |
| 261 r.Build(code, code + arraysize(code)); | 265 r.Build(code, code + arraysize(code)); |
| 262 | 266 |
| 263 WasmInterpreter* interpreter = r.interpreter(); | 267 WasmInterpreter* interpreter = r.interpreter(); |
| 264 WasmInterpreter::Thread* thread = interpreter->GetThread(0); | 268 WasmInterpreter::Thread* thread = interpreter->GetThread(0); |
| 265 | 269 |
| 266 FOR_UINT32_INPUTS(a) { | 270 FOR_UINT32_INPUTS(a) { |
| 267 for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) { | 271 for (uint32_t b = 11; b < 3000000000u; b += 1000000000u) { |
| 268 // Run with and without breakpoints. | 272 // Run with and without breakpoints. |
| 269 for (int do_break = 0; do_break < 2; do_break++) { | 273 for (int do_break = 0; do_break < 2; do_break++) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 286 // Check the thread finished with the right value. | 290 // Check the thread finished with the right value. |
| 287 CHECK_EQ(WasmInterpreter::FINISHED, thread->state()); | 291 CHECK_EQ(WasmInterpreter::FINISHED, thread->state()); |
| 288 uint32_t expected = (*a) & (b); | 292 uint32_t expected = (*a) & (b); |
| 289 CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>()); | 293 CHECK_EQ(expected, thread->GetReturnValue().to<uint32_t>()); |
| 290 } | 294 } |
| 291 } | 295 } |
| 292 } | 296 } |
| 293 } | 297 } |
| 294 | 298 |
| 295 TEST(GrowMemory) { | 299 TEST(GrowMemory) { |
| 296 WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted); | 300 TestingModule module(kExecuteInterpreted); |
| 297 r.module().AddMemory(WasmModule::kPageSize); | 301 WasmRunner<int32_t> r(&module, MachineType::Uint32()); |
| 302 module.AddMemory(WasmModule::kPageSize); |
| 298 BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0))); | 303 BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0))); |
| 299 CHECK_EQ(1, r.Call(1)); | 304 CHECK_EQ(1, r.Call(1)); |
| 300 } | 305 } |
| 301 | 306 |
| 302 TEST(GrowMemoryPreservesData) { | 307 TEST(GrowMemoryPreservesData) { |
| 303 int32_t index = 16; | 308 int32_t index = 16; |
| 304 int32_t value = 2335; | 309 int32_t value = 2335; |
| 305 WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted); | 310 TestingModule module(kExecuteInterpreted); |
| 306 r.module().AddMemory(WasmModule::kPageSize); | 311 WasmRunner<int32_t> r(&module, MachineType::Uint32()); |
| 312 module.AddMemory(WasmModule::kPageSize); |
| 307 BUILD(r, WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), | 313 BUILD(r, WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), |
| 308 WASM_I32V(value)), | 314 WASM_I32V(value)), |
| 309 WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP, | 315 WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP, |
| 310 WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))); | 316 WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))); |
| 311 CHECK_EQ(value, r.Call(1)); | 317 CHECK_EQ(value, r.Call(1)); |
| 312 } | 318 } |
| 313 | 319 |
| 314 TEST(GrowMemoryInvalidSize) { | 320 TEST(GrowMemoryInvalidSize) { |
| 315 { | 321 { |
| 316 // Grow memory by an invalid amount without initial memory. | 322 // Grow memory by an invalid amount without initial memory. |
| 317 WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted); | 323 TestingModule module(kExecuteInterpreted); |
| 324 WasmRunner<int32_t> r(&module, MachineType::Uint32()); |
| 318 BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0))); | 325 BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0))); |
| 319 CHECK_EQ(-1, r.Call(1048575)); | 326 CHECK_EQ(-1, r.Call(1048575)); |
| 320 } | 327 } |
| 321 { | 328 { |
| 322 // Grow memory by an invalid amount without initial memory. | 329 // Grow memory by an invalid amount without initial memory. |
| 323 WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted); | 330 TestingModule module(kExecuteInterpreted); |
| 324 r.module().AddMemory(WasmModule::kPageSize); | 331 WasmRunner<int32_t> r(&module, MachineType::Uint32()); |
| 332 module.AddMemory(WasmModule::kPageSize); |
| 325 BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0))); | 333 BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0))); |
| 326 CHECK_EQ(-1, r.Call(1048575)); | 334 CHECK_EQ(-1, r.Call(1048575)); |
| 327 } | 335 } |
| 328 } | 336 } |
| 329 | 337 |
| 330 TEST(TestPossibleNondeterminism) { | 338 TEST(TestPossibleNondeterminism) { |
| 331 { | 339 { |
| 332 // F32Div may produced NaN | 340 // F32Div may produced NaN |
| 333 WasmRunner<float, float, float> r(kExecuteInterpreted); | 341 TestingModule module(kExecuteInterpreted); |
| 342 WasmRunner<float> r(&module, MachineType::Float32(), |
| 343 MachineType::Float32()); |
| 334 BUILD(r, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 344 BUILD(r, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 335 r.Call(1048575.5f, 2.5f); | 345 r.Call(1048575.5f, 2.5f); |
| 336 CHECK(!r.possible_nondeterminism()); | 346 CHECK(!r.possible_nondeterminism()); |
| 337 r.Call(0.0f, 0.0f); | 347 r.Call(0.0f, 0.0f); |
| 338 CHECK(r.possible_nondeterminism()); | 348 CHECK(r.possible_nondeterminism()); |
| 339 } | 349 } |
| 340 { | 350 { |
| 341 // F32Sqrt may produced NaN | 351 // F32Sqrt may produced NaN |
| 342 WasmRunner<float, float> r(kExecuteInterpreted); | 352 TestingModule module(kExecuteInterpreted); |
| 353 WasmRunner<float> r(&module, MachineType::Float32()); |
| 343 BUILD(r, WASM_F32_SQRT(WASM_GET_LOCAL(0))); | 354 BUILD(r, WASM_F32_SQRT(WASM_GET_LOCAL(0))); |
| 344 r.Call(16.0f); | 355 r.Call(16.0f); |
| 345 CHECK(!r.possible_nondeterminism()); | 356 CHECK(!r.possible_nondeterminism()); |
| 346 r.Call(-1048575.5f); | 357 r.Call(-1048575.5f); |
| 347 CHECK(r.possible_nondeterminism()); | 358 CHECK(r.possible_nondeterminism()); |
| 348 } | 359 } |
| 349 { | 360 { |
| 350 // F32Mul may produced NaN | 361 // F32Mul may produced NaN |
| 351 WasmRunner<float, float, float> r(kExecuteInterpreted); | 362 TestingModule module(kExecuteInterpreted); |
| 363 WasmRunner<float> r(&module, MachineType::Float32(), |
| 364 MachineType::Float32()); |
| 352 BUILD(r, WASM_F32_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 365 BUILD(r, WASM_F32_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 353 r.Call(1048575.5f, 2.5f); | 366 r.Call(1048575.5f, 2.5f); |
| 354 CHECK(!r.possible_nondeterminism()); | 367 CHECK(!r.possible_nondeterminism()); |
| 355 r.Call(std::numeric_limits<float>::infinity(), 0.0f); | 368 r.Call(std::numeric_limits<float>::infinity(), 0.0f); |
| 356 CHECK(r.possible_nondeterminism()); | 369 CHECK(r.possible_nondeterminism()); |
| 357 } | 370 } |
| 358 { | 371 { |
| 359 // F64Div may produced NaN | 372 // F64Div may produced NaN |
| 360 WasmRunner<double, double, double> r(kExecuteInterpreted); | 373 TestingModule module(kExecuteInterpreted); |
| 374 WasmRunner<double> r(&module, MachineType::Float64(), |
| 375 MachineType::Float64()); |
| 361 BUILD(r, WASM_F64_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 376 BUILD(r, WASM_F64_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 362 r.Call(1048575.5, 2.5); | 377 r.Call(1048575.5, 2.5); |
| 363 CHECK(!r.possible_nondeterminism()); | 378 CHECK(!r.possible_nondeterminism()); |
| 364 r.Call(0.0, 0.0); | 379 r.Call(0.0, 0.0); |
| 365 CHECK(r.possible_nondeterminism()); | 380 CHECK(r.possible_nondeterminism()); |
| 366 } | 381 } |
| 367 { | 382 { |
| 368 // F64Sqrt may produced NaN | 383 // F64Sqrt may produced NaN |
| 369 WasmRunner<double, double> r(kExecuteInterpreted); | 384 TestingModule module(kExecuteInterpreted); |
| 385 WasmRunner<double> r(&module, MachineType::Float64()); |
| 370 BUILD(r, WASM_F64_SQRT(WASM_GET_LOCAL(0))); | 386 BUILD(r, WASM_F64_SQRT(WASM_GET_LOCAL(0))); |
| 371 r.Call(1048575.5); | 387 r.Call(1048575.5); |
| 372 CHECK(!r.possible_nondeterminism()); | 388 CHECK(!r.possible_nondeterminism()); |
| 373 r.Call(-1048575.5); | 389 r.Call(-1048575.5); |
| 374 CHECK(r.possible_nondeterminism()); | 390 CHECK(r.possible_nondeterminism()); |
| 375 } | 391 } |
| 376 { | 392 { |
| 377 // F64Mul may produced NaN | 393 // F64Mul may produced NaN |
| 378 WasmRunner<double, double, double> r(kExecuteInterpreted); | 394 TestingModule module(kExecuteInterpreted); |
| 395 WasmRunner<double> r(&module, MachineType::Float64(), |
| 396 MachineType::Float64()); |
| 379 BUILD(r, WASM_F64_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 397 BUILD(r, WASM_F64_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
| 380 r.Call(1048575.5, 2.5); | 398 r.Call(1048575.5, 2.5); |
| 381 CHECK(!r.possible_nondeterminism()); | 399 CHECK(!r.possible_nondeterminism()); |
| 382 r.Call(std::numeric_limits<double>::infinity(), 0.0); | 400 r.Call(std::numeric_limits<double>::infinity(), 0.0); |
| 383 CHECK(r.possible_nondeterminism()); | 401 CHECK(r.possible_nondeterminism()); |
| 384 } | 402 } |
| 385 } | 403 } |
| 386 } // namespace wasm | 404 } // namespace wasm |
| 387 } // namespace internal | 405 } // namespace internal |
| 388 } // namespace v8 | 406 } // namespace v8 |
| OLD | NEW |