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