Floating point division is now relying on underlying FPU and IEEE for behavior with respect to divide by 0
Showing the changes to src/vm/execution_table.cpp (1 of 11 files). Show all
Unified · Split
| @@ -294,6 +294,16 @@ namespace · 293 unmodified lines | |||
| 294 | vt_ref<PrimitiveType>(r.dest) = vt_ref<PrimitiveType>(r.mid) / denom; | 294 | vt_ref<PrimitiveType>(r.dest) = vt_ref<PrimitiveType>(r.mid) / denom; |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | // [SPEC] The C++ defines division by 0 as undefined, however the IEEE standard does | ||
| 298 | // define the behavior. Therefore the behavior is platform dependent and controlled | ||
| 299 | // by the built-in Math module. | ||
| 300 | template<> | ||
| 301 | void _div<real_t>(vm_registers_t &r) | ||
| 302 | { | ||
| 303 | const auto denom = vt_ref<real_t>(r.src); | ||
| 304 | vt_ref<real_t>(r.dest) = vt_ref<real_t>(r.mid) / denom; | ||
| 305 | } | ||
| 306 | |||
| 297 | EXEC_DECL(divb) { _div<byte_t>(r); } | 307 | EXEC_DECL(divb) { _div<byte_t>(r); } |
| 298 | EXEC_DECL(divw) { _div<word_t>(r); } | 308 | EXEC_DECL(divw) { _div<word_t>(r); } |
| 299 | EXEC_DECL(divf) { _div<real_t>(r); } | 309 | EXEC_DECL(divf) { _div<real_t>(r); } |
| @@ -1318,7 +1328,7 @@ namespace · 1018 unmodified lines | |||
| 1318 | 1328 | ||
| 1319 | namespace | 1329 | namespace |
| 1320 | { | 1330 | { |
| 1321 | void new_instance(vm_registers_t &r, const vm_t &vm, const bool zero_memory) | 1331 | void new_instance(vm_registers_t &r, const vm_t &vm) |
| 1322 | { | 1332 | { |
| 1323 | const auto type_id = vt_ref<word_t>(r.src); | 1333 | const auto type_id = vt_ref<word_t>(r.src); |
| 1324 | const auto &types = r.module_ref->type_section; | 1334 | const auto &types = r.module_ref->type_section; |
| @@ -1327,7 +1337,7 @@ namespace · 2 unmodified lines | |||
| 1327 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); | 1337 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); |
| 1328 | 1338 | ||
| 1329 | auto type_desc = types[type_id]; | 1339 | auto type_desc = types[type_id]; |
| 1330 | auto new_alloc = !zero_memory ? vm_alloc_t::allocate(type_desc) : vm_alloc_t::allocate(type_desc, vm_alloc_t::zero_memory); | 1340 | auto new_alloc = vm_alloc_t::allocate(type_desc); |
| 1331 | 1341 | ||
| 1332 | if (type_desc->map_in_bytes > 0) | 1342 | if (type_desc->map_in_bytes > 0) |
| 1333 | vm.get_garbage_collector().track_allocation(new_alloc); | 1343 | vm.get_garbage_collector().track_allocation(new_alloc); |
| @@ -1338,12 +1348,14 @@ namespace · 4 unmodified lines | |||
| 1338 | 1348 | ||
| 1339 | EXEC_DECL(new_) | 1349 | EXEC_DECL(new_) |
| 1340 | { | 1350 | { |
| 1341 | new_instance(r, vm, false /* zero memory */); | 1351 | new_instance(r, vm); |
| 1342 | } | 1352 | } |
| 1343 | 1353 | ||
| 1344 | EXEC_DECL(newz) | 1354 | EXEC_DECL(newz) |
| 1345 | { | 1355 | { |
| 1346 | new_instance(r, vm, true /* zero memory */); | 1356 | // See allocation implementation for guarantee about |
| 1357 | // always using zeroed memory. | ||
| 1358 | new_instance(r, vm); | ||
| 1347 | } | 1359 | } |
| 1348 | 1360 | ||
| 1349 | EXEC_DECL(mnewz) | 1361 | EXEC_DECL(mnewz) |
| @@ -1359,7 +1371,7 @@ namespace · 9 unmodified lines | |||
| 1359 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); | 1371 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); |
| 1360 | 1372 | ||
| 1361 | auto type_desc = types[type_id]; | 1373 | auto type_desc = types[type_id]; |
| 1362 | auto new_alloc = vm_alloc_t::allocate(type_desc, vm_alloc_t::zero_memory); | 1374 | auto new_alloc = vm_alloc_t::allocate(type_desc); |
| 1363 | 1375 | ||
| 1364 | if (type_desc->map_in_bytes > 0) | 1376 | if (type_desc->map_in_bytes > 0) |
| 1365 | vm.get_garbage_collector().track_allocation(new_alloc); | 1377 | vm.get_garbage_collector().track_allocation(new_alloc); |
| @@ -1369,7 +1381,7 @@ namespace · 3 unmodified lines | |||
| 1369 | 1381 | ||
| 1370 | namespace | 1382 | namespace |
| 1371 | { | 1383 | { |
| 1372 | void new_array(vm_registers_t &r, const vm_t &vm, const bool zero_memory) | 1384 | void new_array(vm_registers_t &r, const vm_t &vm) |
| 1373 | { | 1385 | { |
| 1374 | assert(r.module_ref != nullptr); | 1386 | assert(r.module_ref != nullptr); |
| 1375 | const auto &types = r.module_ref->type_section; | 1387 | const auto &types = r.module_ref->type_section; |
| @@ -1381,7 +1393,7 @@ namespace · 5 unmodified lines | |||
| 1381 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); | 1393 | dec_ref_count_and_free(at_val<vm_alloc_t>(r.dest)); |
| 1382 | 1394 | ||
| 1383 | const auto array_size = vt_ref<word_t>(r.src); | 1395 | const auto array_size = vt_ref<word_t>(r.src); |
| 1384 | auto new_array = !zero_memory ? new vm_array_t(type_desc, array_size) : new vm_array_t(type_desc, array_size, vm_alloc_t::zero_memory); | 1396 | auto new_array = new vm_array_t(type_desc, array_size); |
| 1385 | 1397 | ||
| 1386 | if (type_desc->map_in_bytes > 0) | 1398 | if (type_desc->map_in_bytes > 0) |
| 1387 | vm.get_garbage_collector().track_allocation(new_array); | 1399 | vm.get_garbage_collector().track_allocation(new_array); |
| @@ -1392,12 +1404,14 @@ namespace · 4 unmodified lines | |||
| 1392 | 1404 | ||
| 1393 | EXEC_DECL(newa) | 1405 | EXEC_DECL(newa) |
| 1394 | { | 1406 | { |
| 1395 | new_array(r, vm, false /* zero memory */); | 1407 | new_array(r, vm); |
| 1396 | } | 1408 | } |
| 1397 | 1409 | ||
| 1398 | EXEC_DECL(newaz) | 1410 | EXEC_DECL(newaz) |
| 1399 | { | 1411 | { |
| 1400 | new_array(r, vm, true /* zero memory */); | 1412 | // See allocation implementation for guarantee about |
| 1413 | // always using zeroed memory. | ||
| 1414 | new_array(r, vm); | ||
| 1401 | } | 1415 | } |
| 1402 | 1416 | ||
| 1403 | EXEC_DECL(tcmp) | 1417 | EXEC_DECL(tcmp) |