summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorBen Smith <binjimin@gmail.com>2016-05-02 14:47:11 -0700
committerJF Bastien <github@jfbastien.com>2016-05-02 14:47:11 -0700
commit2559cb90937b4b88377a0e17e0725771511a08a7 (patch)
tree3f2576d5cb25e709f7f906510de84ce2c0c34c5a /src/wasm-interpreter.h
parent203d8b2f4021e61dede148a9f0ada0f0b0a02da9 (diff)
downloadbinaryen-2559cb90937b4b88377a0e17e0725771511a08a7.tar.gz
binaryen-2559cb90937b4b88377a0e17e0725771511a08a7.tar.bz2
binaryen-2559cb90937b4b88377a0e17e0725771511a08a7.zip
Fix {i32,i64}.trunc_{s,u}/{f32,f64} in interpreter (#421)
Check the binary representation of the float instead of converting it to a float first.
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h30
1 files changed, 22 insertions, 8 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index 3d4eea722..d0e64c91e 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -640,12 +640,19 @@ private:
double val = value.getFloat();
if (std::isnan(val)) trap("truncSFloat of nan");
if (curr->type == i32) {
- if (val > (double)std::numeric_limits<int32_t>::max() || val < (double)std::numeric_limits<int32_t>::min()) trap("i32.truncSFloat overflow");
+ if (value.type == f32) {
+ if (!isInRangeI32TruncS(value.reinterpreti32())) trap("i32.truncSFloat overflow");
+ } else {
+ if (!isInRangeI32TruncS(value.reinterpreti64())) trap("i32.truncSFloat overflow");
+ }
return Literal(int32_t(val));
} else {
- int64_t converted = (int64_t)val;
- if ((val >= 1 && converted <= 0) || val < (double)LLONG_MIN) trap("i64.truncSFloat overflow");
- return Literal(converted);
+ if (value.type == f32) {
+ if (!isInRangeI64TruncS(value.reinterpreti32())) trap("i64.truncSFloat overflow");
+ } else {
+ if (!isInRangeI64TruncS(value.reinterpreti64())) trap("i64.truncSFloat overflow");
+ }
+ return Literal(int64_t(val));
}
}
@@ -653,12 +660,19 @@ private:
double val = value.getFloat();
if (std::isnan(val)) trap("truncUFloat of nan");
if (curr->type == i32) {
- if (val > (double)std::numeric_limits<uint32_t>::max() || val <= (double)-1) trap("i32.truncUFloat overflow");
+ if (value.type == f32) {
+ if (!isInRangeI32TruncU(value.reinterpreti32())) trap("i32.truncUFloat overflow");
+ } else {
+ if (!isInRangeI32TruncU(value.reinterpreti64())) trap("i32.truncUFloat overflow");
+ }
return Literal(uint32_t(val));
} else {
- uint64_t converted = (uint64_t)val;
- if (converted < val - 1 || val <= (double)-1) trap("i64.truncUFloat overflow");
- return Literal(converted);
+ if (value.type == f32) {
+ if (!isInRangeI64TruncU(value.reinterpreti32())) trap("i64.truncUFloat overflow");
+ } else {
+ if (!isInRangeI64TruncU(value.reinterpreti64())) trap("i64.truncUFloat overflow");
+ }
+ return Literal(uint64_t(val));
}
}