diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm-main.cpp | 4 | ||||
-rw-r--r-- | src/asm2wasm.h | 60 | ||||
-rw-r--r-- | src/binaryen-shell.cpp | 6 | ||||
-rw-r--r-- | src/js/wasm.js-post.js | 5 | ||||
-rw-r--r-- | src/parsing.h | 4 | ||||
-rw-r--r-- | src/s2wasm-main.cpp | 4 | ||||
-rw-r--r-- | src/s2wasm.h | 21 | ||||
-rw-r--r-- | src/support/file.cpp | 25 | ||||
-rw-r--r-- | src/support/file.h | 20 | ||||
-rw-r--r-- | src/wasm-as.cpp | 4 | ||||
-rw-r--r-- | src/wasm-dis.cpp | 4 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 4 | ||||
-rw-r--r-- | src/wasm-js.cpp | 33 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 5 | ||||
-rw-r--r-- | src/wasm.h | 20 | ||||
-rw-r--r-- | src/wasm2asm-main.cpp | 4 |
16 files changed, 158 insertions, 65 deletions
diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp index 56e8a417f..12a06d0de 100644 --- a/src/asm2wasm-main.cpp +++ b/src/asm2wasm-main.cpp @@ -77,7 +77,7 @@ int main(int argc, const char *argv[]) { Asm2WasmPreProcessor pre; auto input( - read_file<std::vector<char>>(options.extra["infile"], options.debug)); + read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); char *start = pre.process(input.data()); if (options.debug) std::cerr << "parsing..." << std::endl; @@ -101,7 +101,7 @@ int main(int argc, const char *argv[]) { } if (options.debug) std::cerr << "printing..." << std::endl; - Output output(options.extra["output"], options.debug); + Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); printWasm(&wasm, output.getStream()); if (mappedGlobals) { diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 4c37b7705..7d9b9652b 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -202,6 +202,8 @@ private: IString Math_ceil; IString Math_sqrt; + IString tempDoublePtr; // imported name of tempDoublePtr + // function types. we fill in this information as we see // uses, in the first pass @@ -483,6 +485,13 @@ void Asm2WasmBuilder::processAsm(Ref ast) { } else { assert(module[0] == NAME); moduleName = module[1]->getIString(); + if (moduleName == ENV) { + if (imported[2] == TEMP_DOUBLE_PTR) { + assert(tempDoublePtr.isNull()); + tempDoublePtr = name; + // we don't return here, as we can only optimize out some uses of tDP. So it remains imported + } + } } auto import = allocator.alloc<Import>(); import->name = name; @@ -1404,6 +1413,57 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { ret->type = ret->ifTrue->type; return ret; } else if (what == SEQ) { + // Some (x, y) patterns can be optimized, like bitcasts, + // (HEAP32[tempDoublePtr >> 2] = i, Math_fround(HEAPF32[tempDoublePtr >> 2])); // i32->f32 + // (HEAP32[tempDoublePtr >> 2] = i, +HEAPF32[tempDoublePtr >> 2]); // i32->f32, no fround + // (HEAPF32[tempDoublePtr >> 2] = f, HEAP32[tempDoublePtr >> 2] | 0); // f32->i32 + if (ast[1][0] == ASSIGN && ast[1][2][0] == SUB && ast[1][2][1][0] == NAME && ast[1][2][2][0] == BINARY && ast[1][2][2][1] == RSHIFT && + ast[1][2][2][2][0] == NAME && ast[1][2][2][2][1] == tempDoublePtr && ast[1][2][2][3][0] == NUM && ast[1][2][2][3][1]->getNumber() == 2) { + // (?[tempDoublePtr >> 2] = ?, ?) so far + auto heap = ast[1][2][1][1]->getIString(); + if (views.find(heap) != views.end()) { + AsmType writeType = views[heap].type; + AsmType readType = ASM_NONE; + Ref readValue; + if (ast[2][0] == BINARY && ast[2][1] == OR && ast[2][3][0] == NUM && ast[2][3][1]->getNumber() == 0) { + readType = ASM_INT; + readValue = ast[2][2]; + } else if (ast[2][0] == UNARY_PREFIX && ast[2][1] == PLUS) { + readType = ASM_DOUBLE; + readValue = ast[2][2]; + } else if (ast[2][0] == CALL && ast[2][1][0] == NAME && ast[2][1][1] == Math_fround) { + readType = ASM_FLOAT; + readValue = ast[2][2][0]; + } + if (readType != ASM_NONE) { + if (readValue[0] == SUB && readValue[1][0] == NAME && readValue[2][0] == BINARY && readValue[2][1] == RSHIFT && + readValue[2][2][0] == NAME && readValue[2][2][1] == tempDoublePtr && readValue[2][3][0] == NUM && readValue[2][3][1]->getNumber() == 2) { + // pattern looks right! + Ref writtenValue = ast[1][3]; + if (writeType == ASM_INT && (readType == ASM_FLOAT || readType == ASM_DOUBLE)) { + auto conv = allocator.alloc<Unary>(); + conv->op = ReinterpretInt; + conv->value = process(writtenValue); + conv->type = WasmType::f32; + if (readType == ASM_DOUBLE) { + auto promote = allocator.alloc<Unary>(); + promote->op = PromoteFloat32; + promote->value = conv; + promote->type = WasmType::f64; + return promote; + } + return conv; + } else if (writeType == ASM_FLOAT && readType == ASM_INT) { + auto conv = allocator.alloc<Unary>(); + conv->op = ReinterpretFloat; + conv->value = process(writtenValue); + conv->type = WasmType::i32; + return conv; + } + } + } + } + } auto ret = allocator.alloc<Block>(); ret->list.push_back(process(ast[1])); ret->list.push_back(process(ast[2])); diff --git a/src/binaryen-shell.cpp b/src/binaryen-shell.cpp index 78ff91150..c2b6fcaa7 100644 --- a/src/binaryen-shell.cpp +++ b/src/binaryen-shell.cpp @@ -66,8 +66,8 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface { std::vector<char> memory; template <typename T> static bool aligned(const char* address) { - static_assert(!(alignof(T) & (alignof(T) - 1)), "must be a power of 2"); - return 0 == (reinterpret_cast<uintptr_t>(address) & (alignof(T) - 1)); + static_assert(!(sizeof(T) & (sizeof(T) - 1)), "must be a power of 2"); + return 0 == (reinterpret_cast<uintptr_t>(address) & (sizeof(T) - 1)); } Memory(Memory&) = delete; Memory& operator=(const Memory&) = delete; @@ -372,7 +372,7 @@ int main(int argc, const char* argv[]) { } options.parse(argc, argv); - auto input(read_file<std::vector<char>>(options.extra["infile"], options.debug)); + auto input(read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); if (options.debug) std::cerr << "parsing text to s-expressions...\n"; SExpressionParser parser(input.data()); diff --git a/src/js/wasm.js-post.js b/src/js/wasm.js-post.js index 9851fc777..fefc2f12a 100644 --- a/src/js/wasm.js-post.js +++ b/src/js/wasm.js-post.js @@ -36,6 +36,8 @@ function integrateWasmJS(Module) { // utilities + var wasmPageSize = 64*1024; + var asm2wasmImports = { // special asm2wasm imports "f64-rem": function(x, y) { return x % y; @@ -94,8 +96,9 @@ function integrateWasmJS(Module) { updateGlobalBuffer(newBuffer); updateGlobalBufferViews(); Module['reallocBuffer'] = function(size) { + size = Math.ceil(size / wasmPageSize) * wasmPageSize; // round up to wasm page size var old = Module['buffer']; - exports['__growWasmMemory'](size); // tiny wasm method that just does grow_memory + exports['__growWasmMemory'](size / wasmPageSize); // tiny wasm method that just does grow_memory return Module['buffer'] !== old ? Module['buffer'] : null; // if it was reallocated, it changed }; } diff --git a/src/parsing.h b/src/parsing.h index ed2f65b59..935750537 100644 --- a/src/parsing.h +++ b/src/parsing.h @@ -79,7 +79,7 @@ Expression* parseConst(cashew::IString s, WasmType type, MixedArena& allocator) pattern = 0x7fc00000U; } if (negative) pattern |= 0x80000000U; - if (!isnan(bit_cast<float>(pattern))) pattern |= 1U; + if (!std::isnan(bit_cast<float>(pattern))) pattern |= 1U; ret->value = Literal(pattern).castToF32(); break; } @@ -93,7 +93,7 @@ Expression* parseConst(cashew::IString s, WasmType type, MixedArena& allocator) pattern = 0x7ff8000000000000UL; } if (negative) pattern |= 0x8000000000000000ULL; - if (!isnan(bit_cast<double>(pattern))) pattern |= 1ULL; + if (!std::isnan(bit_cast<double>(pattern))) pattern |= 1ULL; ret->value = Literal(pattern).castToF64(); break; } diff --git a/src/s2wasm-main.cpp b/src/s2wasm-main.cpp index 40009cbc9..8cbb7f5f5 100644 --- a/src/s2wasm-main.cpp +++ b/src/s2wasm-main.cpp @@ -74,7 +74,7 @@ int main(int argc, const char *argv[]) { }); options.parse(argc, argv); - auto input(read_file<std::string>(options.extra["infile"], options.debug)); + auto input(read_file<std::string>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); if (options.debug) std::cerr << "Parsing and wasming..." << std::endl; AllocatingModule wasm; @@ -103,7 +103,7 @@ int main(int argc, const char *argv[]) { s2wasm.emscriptenGlue(meta); if (options.debug) std::cerr << "Printing..." << std::endl; - Output output(options.extra["output"], options.debug); + Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); printWasm(&wasm, output.getStream()); output << meta.str() << std::endl; diff --git a/src/s2wasm.h b/src/s2wasm.h index f4c83fe65..1fa624dd0 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -677,13 +677,13 @@ class S2WasmBuilder { auto makeHost = [&](HostOp op) { Name assign = getAssign(); auto curr = allocator.alloc<Host>(); - curr->op = MemorySize; + curr->op = op; setOutput(curr, assign); }; auto makeHost1 = [&](HostOp op) { Name assign = getAssign(); auto curr = allocator.alloc<Host>(); - curr->op = MemorySize; + curr->op = op; curr->operands.push_back(getInput()); setOutput(curr, assign); }; @@ -752,16 +752,7 @@ class S2WasmBuilder { indirect->operands.push_back(inputs[i]); } setOutput(indirect, assign); - auto typeName = cashew::IString((std::string("FUNCSIG_") + getSig(indirect)).c_str(), false); - if (wasm.functionTypesMap.count(typeName) == 0) { - auto type = allocator.alloc<FunctionType>(); - *type = sigToFunctionType(getSig(indirect)); - type->name = typeName; - wasm.addFunctionType(type); - indirect->fullType = type; - } else { - indirect->fullType = wasm.functionTypesMap[typeName]; - } + indirect->fullType = wasm.functionTypesMap[ensureFunctionType(getSig(indirect), &wasm, allocator)->name]; } else { // non-indirect call CallBase* curr; @@ -1314,6 +1305,12 @@ class S2WasmBuilder { block->finalize(); } } + + // ensure an explicit function type for indirect call targets + for (auto& name : wasm.table.names) { + auto* func = wasm.functionsMap[name]; + func->type = ensureFunctionType(getSig(func), &wasm, allocator)->name; + } } template<class C> diff --git a/src/support/file.cpp b/src/support/file.cpp index c93086990..b71361d99 100644 --- a/src/support/file.cpp +++ b/src/support/file.cpp @@ -20,16 +20,19 @@ #include <limits> template <typename T> -T wasm::read_file(const std::string &filename, bool debug) { - if (debug) std::cerr << "Loading '" << filename << "'..." << std::endl; - std::ifstream infile(filename); +T wasm::read_file(const std::string &filename, Flags::BinaryOption binary, Flags::DebugOption debug) { + if (debug == Flags::Debug) std::cerr << "Loading '" << filename << "'..." << std::endl; + std::ifstream infile; + auto flags = std::ifstream::in; + if (binary == Flags::Binary) flags |= std::ifstream::binary; + infile.open(filename, flags); if (!infile.is_open()) { std::cerr << "Failed opening '" << filename << "'" << std::endl; exit(EXIT_FAILURE); } infile.seekg(0, std::ios::end); std::streampos insize = infile.tellg(); - if (size_t(insize) >= std::numeric_limits<size_t>::max()) { + if (uint64_t(insize) >= std::numeric_limits<size_t>::max()) { // Building a 32-bit executable where size_t == 32 bits, we are not able to create strings larger than 2^32 bytes in length, so must abort here. std::cerr << "Failed opening '" << filename << "': Input file too large: " << insize << " bytes. Try rebuilding in 64-bit mode." << std::endl; exit(EXIT_FAILURE); @@ -41,15 +44,17 @@ T wasm::read_file(const std::string &filename, bool debug) { } // Explicit instantiations for the explicit specializations. -template std::string wasm::read_file<>(const std::string &, bool); -template std::vector<char> wasm::read_file<>(const std::string &, bool); +template std::string wasm::read_file<>(const std::string &, Flags::BinaryOption, Flags::DebugOption); +template std::vector<char> wasm::read_file<>(const std::string &, Flags::BinaryOption, Flags::DebugOption); -wasm::Output::Output(const std::string &filename, bool debug) - : outfile(), out([this, filename, debug]() { +wasm::Output::Output(const std::string &filename, Flags::BinaryOption binary, Flags::DebugOption debug) + : outfile(), out([this, filename, binary, debug]() { std::streambuf *buffer; if (filename.size()) { - if (debug) std::cerr << "Opening '" << filename << std::endl; - outfile.open(filename, std::ofstream::out | std::ofstream::trunc); + if (debug == Flags::Debug) std::cerr << "Opening '" << filename << std::endl; + auto flags = std::ofstream::out | std::ofstream::trunc; + if (binary == Flags::Binary) flags |= std::ofstream::binary; + outfile.open(filename, flags); if (!outfile.is_open()) { std::cerr << "Failed opening '" << filename << "'" << std::endl; exit(EXIT_FAILURE); diff --git a/src/support/file.h b/src/support/file.h index 47f7ececb..01c7a8546 100644 --- a/src/support/file.h +++ b/src/support/file.h @@ -28,16 +28,28 @@ #include <vector> namespace wasm { + +namespace Flags { + enum BinaryOption { + Binary, + Text + }; + enum DebugOption { + Debug, + Release + }; +} + template <typename T> -T read_file(const std::string &filename, bool debug); +T read_file(const std::string &filename, Flags::BinaryOption binary, Flags::DebugOption debug); // Declare the valid explicit specializations. -extern template std::string read_file<>(const std::string &, bool); -extern template std::vector<char> read_file<>(const std::string &, bool); +extern template std::string read_file<>(const std::string &, Flags::BinaryOption, Flags::DebugOption); +extern template std::vector<char> read_file<>(const std::string &, Flags::BinaryOption, Flags::DebugOption); class Output { public: // An empty filename will open stdout instead. - Output(const std::string &filename, bool debug); + Output(const std::string &filename, Flags::BinaryOption binary, Flags::DebugOption debug); ~Output() = default; template <typename T> std::ostream &operator<<(const T &v) { diff --git a/src/wasm-as.cpp b/src/wasm-as.cpp index 48ec0fc4c..c2a8abc6e 100644 --- a/src/wasm-as.cpp +++ b/src/wasm-as.cpp @@ -41,7 +41,7 @@ int main(int argc, const char *argv[]) { }); options.parse(argc, argv); - auto input(read_file<std::string>(options.extra["infile"], options.debug)); + auto input(read_file<std::string>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); if (options.debug) std::cerr << "s-parsing..." << std::endl; SExpressionParser parser(const_cast<char*>(input.c_str())); @@ -57,7 +57,7 @@ int main(int argc, const char *argv[]) { writer.write(); if (options.debug) std::cerr << "writing to output..." << std::endl; - Output output(options.extra["output"], options.debug); + Output output(options.extra["output"], Flags::Binary, options.debug ? Flags::Debug : Flags::Release); buffer.writeTo(output); if (options.debug) std::cerr << "Done." << std::endl; diff --git a/src/wasm-dis.cpp b/src/wasm-dis.cpp index 7486e0bbd..c3197a1a2 100644 --- a/src/wasm-dis.cpp +++ b/src/wasm-dis.cpp @@ -41,7 +41,7 @@ int main(int argc, const char *argv[]) { }); options.parse(argc, argv); - auto input(read_file<std::vector<char>>(options.extra["infile"], options.debug)); + auto input(read_file<std::vector<char>>(options.extra["infile"], Flags::Binary, options.debug ? Flags::Debug : Flags::Release)); if (options.debug) std::cerr << "parsing binary..." << std::endl; AllocatingModule wasm; @@ -49,7 +49,7 @@ int main(int argc, const char *argv[]) { parser.read(); if (options.debug) std::cerr << "Printing..." << std::endl; - Output output(options.extra["output"], options.debug); + Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); printWasm(&wasm, output.getStream()); output << '\n'; diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index e7a5d6d14..4af410de1 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -636,7 +636,7 @@ private: Literal truncSFloat(Unary* curr, Literal value) { double val = value.getFloat(); - if (isnan(val)) trap("truncSFloat of nan"); + 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"); return Literal(int32_t(val)); @@ -649,7 +649,7 @@ private: Literal truncUFloat(Unary* curr, Literal value) { double val = value.getFloat(); - if (isnan(val)) trap("truncUFloat of nan"); + 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"); return Literal(uint32_t(val)); diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index d978e4a2a..1db313727 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -177,6 +177,18 @@ extern "C" void EMSCRIPTEN_KEEPALIVE instantiate() { }, curr->name.str); } + // verify imports are provided + for (auto& pair : module->importsMap) { + auto& name = pair.first; + auto* import = pair.second; + EM_ASM_({ + var mod = Pointer_stringify($0); + var base = Pointer_stringify($1); + var name = Pointer_stringify($2); + assert(Module['lookupImport'](mod, base), 'checking import ' + name + ' = ' + mod + '.' + base); + }, import->module.str, import->base.str, name.str); + } + if (wasmJSDebug) std::cerr << "creating instance...\n"; struct JSExternalInterface : ModuleInstance::ExternalInterface { @@ -267,26 +279,31 @@ extern "C" void EMSCRIPTEN_KEEPALIVE instantiate() { } // nicely aligned if (!isWasmTypeFloat(load->type)) { + int32_t ret; if (load->bytes == 1) { if (load->signed_) { - return Literal(EM_ASM_INT({ return Module['info'].parent['HEAP8'][$0] }, addr)); + ret = EM_ASM_INT({ return Module['info'].parent['HEAP8'][$0] }, addr); } else { - return Literal(EM_ASM_INT({ return Module['info'].parent['HEAPU8'][$0] }, addr)); + ret = EM_ASM_INT({ return Module['info'].parent['HEAPU8'][$0] }, addr); } } else if (load->bytes == 2) { if (load->signed_) { - return Literal(EM_ASM_INT({ return Module['info'].parent['HEAP16'][$0 >> 1] }, addr)); + ret = EM_ASM_INT({ return Module['info'].parent['HEAP16'][$0 >> 1] }, addr); } else { - return Literal(EM_ASM_INT({ return Module['info'].parent['HEAPU16'][$0 >> 1] }, addr)); + ret = EM_ASM_INT({ return Module['info'].parent['HEAPU16'][$0 >> 1] }, addr); } } else if (load->bytes == 4) { if (load->signed_) { - return Literal(EM_ASM_INT({ return Module['info'].parent['HEAP32'][$0 >> 2] }, addr)); + ret = EM_ASM_INT({ return Module['info'].parent['HEAP32'][$0 >> 2] }, addr); } else { - return Literal(EM_ASM_INT({ return Module['info'].parent['HEAPU32'][$0 >> 2] }, addr)); + ret = EM_ASM_INT({ return Module['info'].parent['HEAPU32'][$0 >> 2] }, addr); } - } - abort(); + } else if (load->bytes == 8) { + uint32_t low = EM_ASM_INT({ return Module['info'].parent['HEAP32'][$0 >> 2] }, addr); + uint32_t high = EM_ASM_INT({ return Module['info'].parent['HEAP32'][$0 >> 2] }, addr + 4); + return Literal(int64_t(low) | (int64_t(high) << 32)); + } else abort(); + return load->type == i32 ? Literal(ret) : Literal(int64_t(ret)); } else { if (load->bytes == 4) { return Literal((float)EM_ASM_DOUBLE({ return Module['info'].parent['HEAPF32'][$0 >> 2] }, addr)); diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 6b03433b5..95f8a280d 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -453,9 +453,8 @@ public: // type.operation (e.g. i32.add) WasmType type = stringToWasmType(str, false, true); // Local copy to index into op without bounds checking. - const size_t maxNameSize = 15; - char op[maxNameSize + 1]; - memset(op, 0, maxNameSize + 1); // ensure the whole string is cleared. + enum { maxNameSize = 15 }; + char op[maxNameSize + 1] = {'\0'}; strncpy(op, dot + 1, maxNameSize); switch (op[0]) { case 'a': { diff --git a/src/wasm.h b/src/wasm.h index 7422dd85d..af767b688 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -233,7 +233,7 @@ public: } static void printFloat(std::ostream &o, float f) { - if (isnan(f)) { + if (std::isnan(f)) { const char *sign = std::signbit(f) ? "-" : ""; o << sign << "nan"; if (uint32_t payload = ~0xff800000u & bit_cast<uint32_t>(f)) { @@ -249,7 +249,7 @@ public: o << "-0"; return; } - if (isnan(d)) { + if (std::isnan(d)) { const char *sign = std::signbit(d) ? "-" : ""; o << sign << "nan"; if (uint64_t payload = ~0xfff0000000000000ull & bit_cast<uint64_t>(d)) { @@ -628,8 +628,8 @@ public: auto l = getf32(), r = other.getf32(); if (l == r && l == 0) return Literal(std::signbit(l) ? l : r); auto result = std::min(l, r); - bool lnan = isnan(l), rnan = isnan(r); - if (!isnan(result) && !lnan && !rnan) return Literal(result); + bool lnan = std::isnan(l), rnan = std::isnan(r); + if (!std::isnan(result) && !lnan && !rnan) return Literal(result); if (!lnan && !rnan) return Literal((int32_t)0x7fc00000).castToF32(); return Literal(lnan ? l : r).castToI32().or_(Literal(0xc00000)).castToF32(); } @@ -637,8 +637,8 @@ public: auto l = getf64(), r = other.getf64(); if (l == r && l == 0) return Literal(std::signbit(l) ? l : r); auto result = std::min(l, r); - bool lnan = isnan(l), rnan = isnan(r); - if (!isnan(result) && !lnan && !rnan) return Literal(result); + bool lnan = std::isnan(l), rnan = std::isnan(r); + if (!std::isnan(result) && !lnan && !rnan) return Literal(result); if (!lnan && !rnan) return Literal((int64_t)0x7ff8000000000000LL).castToF64(); return Literal(lnan ? l : r).castToI64().or_(Literal(int64_t(0x8000000000000LL))).castToF64(); } @@ -651,8 +651,8 @@ public: auto l = getf32(), r = other.getf32(); if (l == r && l == 0) return Literal(std::signbit(l) ? r : l); auto result = std::max(l, r); - bool lnan = isnan(l), rnan = isnan(r); - if (!isnan(result) && !lnan && !rnan) return Literal(result); + bool lnan = std::isnan(l), rnan = std::isnan(r); + if (!std::isnan(result) && !lnan && !rnan) return Literal(result); if (!lnan && !rnan) return Literal((int32_t)0x7fc00000).castToF32(); return Literal(lnan ? l : r).castToI32().or_(Literal(0xc00000)).castToF32(); } @@ -660,8 +660,8 @@ public: auto l = getf64(), r = other.getf64(); if (l == r && l == 0) return Literal(std::signbit(l) ? r : l); auto result = std::max(l, r); - bool lnan = isnan(l), rnan = isnan(r); - if (!isnan(result) && !lnan && !rnan) return Literal(result); + bool lnan = std::isnan(l), rnan = std::isnan(r); + if (!std::isnan(result) && !lnan && !rnan) return Literal(result); if (!lnan && !rnan) return Literal((int64_t)0x7ff8000000000000LL).castToF64(); return Literal(lnan ? l : r).castToI64().or_(Literal(int64_t(0x8000000000000LL))).castToF64(); } diff --git a/src/wasm2asm-main.cpp b/src/wasm2asm-main.cpp index c75272b8d..2234f2343 100644 --- a/src/wasm2asm-main.cpp +++ b/src/wasm2asm-main.cpp @@ -44,7 +44,7 @@ int main(int argc, const char *argv[]) { options.parse(argc, argv); auto input( - read_file<std::vector<char>>(options.extra["infile"], options.debug)); + read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release)); if (options.debug) std::cerr << "s-parsing..." << std::endl; SExpressionParser parser(input.data()); @@ -67,7 +67,7 @@ int main(int argc, const char *argv[]) { if (options.debug) std::cerr << "j-printing..." << std::endl; JSPrinter jser(true, true, asmjs); jser.printAst(); - Output output(options.extra["output"], options.debug); + Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); output << jser.buffer << std::endl; if (options.debug) std::cerr << "done." << std::endl; |