diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-12-10 16:10:57 -0500 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-12-10 16:10:57 -0500 |
commit | 3bb2ec9cbaece20ce5930db64aa82d2018bbc10d (patch) | |
tree | e787f88d5640c720f74dc182941543cffab419f0 | |
parent | d05c5eb177687b3b0e41683027720b3d03b77ced (diff) | |
download | binaryen-3bb2ec9cbaece20ce5930db64aa82d2018bbc10d.tar.gz binaryen-3bb2ec9cbaece20ce5930db64aa82d2018bbc10d.tar.bz2 binaryen-3bb2ec9cbaece20ce5930db64aa82d2018bbc10d.zip |
refactor const parsing
-rw-r--r-- | src/parsing.h | 151 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 140 |
2 files changed, 154 insertions, 137 deletions
diff --git a/src/parsing.h b/src/parsing.h new file mode 100644 index 000000000..1a207a3ab --- /dev/null +++ b/src/parsing.h @@ -0,0 +1,151 @@ + +#include "wasm.h" +#include "shared-constants.h" +#include "mixed_arena.h" + +namespace wasm { + +Expression* parseConst(cashew::IString s, WasmType type, MixedArena& allocator) { + const char *str = s.str; + auto ret = allocator.alloc<Const>(); + ret->type = ret->value.type = type; + if (isWasmTypeFloat(type)) { + if (s == INFINITY_) { + switch (type) { + case f32: ret->value.f32 = std::numeric_limits<float>::infinity(); break; + case f64: ret->value.f64 = std::numeric_limits<double>::infinity(); break; + default: return nullptr; + } + //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; + return ret; + } + if (s == NEG_INFINITY) { + switch (type) { + case f32: ret->value.f32 = -std::numeric_limits<float>::infinity(); break; + case f64: ret->value.f64 = -std::numeric_limits<double>::infinity(); break; + default: return nullptr; + } + //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; + return ret; + } + if (s == NAN_) { + switch (type) { + case f32: ret->value.f32 = std::nan(""); break; + case f64: ret->value.f64 = std::nan(""); break; + default: return nullptr; + } + //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; + return ret; + } + bool negative = str[0] == '-'; + const char *positive = negative ? str + 1 : str; + if (positive[0] == '+') positive++; + if (positive[0] == 'n' && positive[1] == 'a' && positive[2] == 'n') { + const char * modifier = positive[3] == ':' ? positive + 4 : nullptr; + assert(modifier ? positive[4] == '0' && positive[5] == 'x' : 1); + switch (type) { + case f32: { + union { + uint32_t pattern; + float f; + } u; + if (modifier) { + std::istringstream istr(modifier); + istr >> std::hex >> u.pattern; + u.pattern |= 0x7f800000; + } else { + u.pattern = 0x7fc00000; + } + if (negative) u.pattern |= 0x80000000; + if (!isnan(u.f)) u.pattern |= 1; + assert(isnan(u.f)); + ret->value.f32 = u.f; + break; + } + case f64: { + union { + uint64_t pattern; + double d; + } u; + if (modifier) { + std::istringstream istr(modifier); + istr >> std::hex >> u.pattern; + u.pattern |= 0x7ff0000000000000LL; + } else { + u.pattern = 0x7ff8000000000000L; + } + if (negative) u.pattern |= 0x8000000000000000LL; + if (!isnan(u.d)) u.pattern |= 1; + assert(isnan(u.d)); + ret->value.f64 = u.d; + break; + } + default: return nullptr; + } + //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; + return ret; + } + if (s == NEG_NAN) { + switch (type) { + case f32: ret->value.f32 = -std::nan(""); break; + case f64: ret->value.f64 = -std::nan(""); break; + default: return nullptr; + } + //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; + return ret; + } + } + switch (type) { + case i32: { + if ((str[0] == '0' && str[1] == 'x') || (str[0] == '-' && str[1] == '0' && str[2] == 'x')) { + bool negative = str[0] == '-'; + if (negative) str++; + std::istringstream istr(str); + uint32_t temp; + istr >> std::hex >> temp; + ret->value.i32 = negative ? -temp : temp; + } else { + std::istringstream istr(str); + int32_t temp; + istr >> temp; + ret->value.i32 = temp; + } + break; + } + case i64: { + if ((str[0] == '0' && str[1] == 'x') || (str[0] == '-' && str[1] == '0' && str[2] == 'x')) { + bool negative = str[0] == '-'; + if (negative) str++; + std::istringstream istr(str); + uint64_t temp; + istr >> std::hex >> temp; + ret->value.i64 = negative ? -temp : temp; + } else { + std::istringstream istr(str); + int64_t temp; + istr >> temp; + ret->value.i64 = temp; + } + break; + } + case f32: { + char *end; + ret->value.f32 = strtof(str, &end); + assert(!isnan(ret->value.f32)); + break; + } + case f64: { + char *end; + ret->value.f64 = strtod(str, &end); + assert(!isnan(ret->value.f64)); + break; + } + default: return nullptr; + } + //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; + return ret; +} + + +} // namespace wasm + diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 792867981..c84c93dc9 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -10,6 +10,7 @@ #include "wasm.h" #include "mixed_arena.h" #include "shared-constants.h" +#include "parsing.h" namespace wasm { @@ -674,143 +675,8 @@ private: } Expression* makeConst(Element& s, WasmType type) { - const char *str = s[1]->c_str(); - auto ret = allocator.alloc<Const>(); - ret->type = ret->value.type = type; - if (isWasmTypeFloat(type)) { - if (s[1]->str() == INFINITY_) { - switch (type) { - case f32: ret->value.f32 = std::numeric_limits<float>::infinity(); break; - case f64: ret->value.f64 = std::numeric_limits<double>::infinity(); break; - default: onError(); - } - //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; - return ret; - } - if (s[1]->str() == NEG_INFINITY) { - switch (type) { - case f32: ret->value.f32 = -std::numeric_limits<float>::infinity(); break; - case f64: ret->value.f64 = -std::numeric_limits<double>::infinity(); break; - default: onError(); - } - //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; - return ret; - } - if (s[1]->str() == NAN_) { - switch (type) { - case f32: ret->value.f32 = std::nan(""); break; - case f64: ret->value.f64 = std::nan(""); break; - default: onError(); - } - //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; - return ret; - } - bool negative = str[0] == '-'; - const char *positive = negative ? str + 1 : str; - if (positive[0] == '+') positive++; - if (positive[0] == 'n' && positive[1] == 'a' && positive[2] == 'n') { - const char * modifier = positive[3] == ':' ? positive + 4 : nullptr; - assert(modifier ? positive[4] == '0' && positive[5] == 'x' : 1); - switch (type) { - case f32: { - union { - uint32_t pattern; - float f; - } u; - if (modifier) { - std::istringstream istr(modifier); - istr >> std::hex >> u.pattern; - u.pattern |= 0x7f800000; - } else { - u.pattern = 0x7fc00000; - } - if (negative) u.pattern |= 0x80000000; - if (!isnan(u.f)) u.pattern |= 1; - assert(isnan(u.f)); - ret->value.f32 = u.f; - break; - } - case f64: { - union { - uint64_t pattern; - double d; - } u; - if (modifier) { - std::istringstream istr(modifier); - istr >> std::hex >> u.pattern; - u.pattern |= 0x7ff0000000000000LL; - } else { - u.pattern = 0x7ff8000000000000L; - } - if (negative) u.pattern |= 0x8000000000000000LL; - if (!isnan(u.d)) u.pattern |= 1; - assert(isnan(u.d)); - ret->value.f64 = u.d; - break; - } - default: onError(); - } - //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; - return ret; - } - if (s[1]->str() == NEG_NAN) { - switch (type) { - case f32: ret->value.f32 = -std::nan(""); break; - case f64: ret->value.f64 = -std::nan(""); break; - default: onError(); - } - //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; - return ret; - } - } - switch (type) { - case i32: { - if ((str[0] == '0' && str[1] == 'x') || (str[0] == '-' && str[1] == '0' && str[2] == 'x')) { - bool negative = str[0] == '-'; - if (negative) str++; - std::istringstream istr(str); - uint32_t temp; - istr >> std::hex >> temp; - ret->value.i32 = negative ? -temp : temp; - } else { - std::istringstream istr(str); - int32_t temp; - istr >> temp; - ret->value.i32 = temp; - } - break; - } - case i64: { - if ((str[0] == '0' && str[1] == 'x') || (str[0] == '-' && str[1] == '0' && str[2] == 'x')) { - bool negative = str[0] == '-'; - if (negative) str++; - std::istringstream istr(str); - uint64_t temp; - istr >> std::hex >> temp; - ret->value.i64 = negative ? -temp : temp; - } else { - std::istringstream istr(str); - int64_t temp; - istr >> temp; - ret->value.i64 = temp; - } - break; - } - case f32: { - char *end; - ret->value.f32 = strtof(str, &end); - assert(!isnan(ret->value.f32)); - break; - } - case f64: { - char *end; - ret->value.f64 = strtod(str, &end); - assert(!isnan(ret->value.f64)); - break; - } - default: onError(); - } - //std::cerr << "make constant " << str << " ==> " << ret->value << '\n'; + auto ret = parseConst(s[1]->str(), type, allocator); + if (!ret) onError(); return ret; } |