summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm-main.cpp8
-rw-r--r--src/asm2wasm.h67
2 files changed, 42 insertions, 33 deletions
diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp
index 73f6853d8..cbcb3b547 100644
--- a/src/asm2wasm-main.cpp
+++ b/src/asm2wasm-main.cpp
@@ -29,6 +29,8 @@ using namespace cashew;
using namespace wasm;
int main(int argc, const char *argv[]) {
+ bool imprecise = false;
+
Options options("asm2wasm", "Translate asm.js files to .wast files");
options
.add("--output", "-o", "Output file (stdout if not specified)",
@@ -45,6 +47,10 @@ int main(int argc, const char *argv[]) {
[](Options *o, const std::string &argument) {
o->extra["total memory"] = argument;
})
+ .add("--imprecise", "-i", "Imprecise optimizations", Options::Arguments::Zero,
+ [&imprecise](Options *o, const std::string &) {
+ imprecise = true;
+ })
.add_positional("INFILE", Options::Arguments::One,
[](Options *o, const std::string &argument) {
o->extra["infile"] = argument;
@@ -81,7 +87,7 @@ int main(int argc, const char *argv[]) {
if (options.debug) std::cerr << "wasming..." << std::endl;
AllocatingModule wasm;
wasm.memory.initial = wasm.memory.max = totalMemory / Memory::kPageSize;
- Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth, options.debug);
+ Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth, options.debug, imprecise);
asm2wasm.processAsm(asmjs);
if (options.debug) std::cerr << "optimizing..." << std::endl;
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index 2d024665e..bf59d08ad 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -151,6 +151,7 @@ class Asm2WasmBuilder {
bool memoryGrowth;
bool debug;
+ bool imprecise;
public:
std::map<IString, MappedGlobal> mappedGlobals;
@@ -254,13 +255,14 @@ private:
}
public:
- Asm2WasmBuilder(AllocatingModule& wasm, bool memoryGrowth, bool debug)
+ Asm2WasmBuilder(AllocatingModule& wasm, bool memoryGrowth, bool debug, bool imprecise)
: wasm(wasm),
allocator(wasm.allocator),
nextGlobal(8),
maxGlobal(1000),
memoryGrowth(memoryGrowth),
- debug(debug) {}
+ debug(debug),
+ imprecise(imprecise) {}
void processAsm(Ref ast);
void optimize();
@@ -1009,37 +1011,38 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
} else if (ast[1] == B_NOT) {
// ~, might be ~~ as a coercion or just a not
if (ast[2][0] == UNARY_PREFIX && ast[2][1] == B_NOT) {
-#if 0
- auto ret = allocator.alloc<Unary>();
- ret->op = TruncSFloat64; // equivalent to U, except for error handling, which asm.js doesn't have anyhow
- ret->value = process(ast[2][2]);
- ret->type = WasmType::i32;
- return ret;
-#endif
- // WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we must emulate that
- CallImport *ret = allocator.alloc<CallImport>();
- ret->target = F64_TO_INT;
- auto input = process(ast[2][2]);
- if (input->type == f32) {
- auto conv = allocator.alloc<Unary>();
- conv->op = PromoteFloat32;
- conv->value = input;
- conv->type = WasmType::f64;
- input = conv;
- }
- ret->operands.push_back(input);
- ret->type = i32;
- static bool addedImport = false;
- if (!addedImport) {
- addedImport = true;
- auto import = allocator.alloc<Import>(); // f64-to-int = asm2wasm.f64-to-int;
- import->name = F64_TO_INT;
- import->module = ASM2WASM;
- import->base = F64_TO_INT;
- import->type = ensureFunctionType("id", &wasm, allocator);
- wasm.addImport(import);
+ if (imprecise) {
+ auto ret = allocator.alloc<Unary>();
+ ret->value = process(ast[2][2]);
+ ret->op = ret->value->type == f64 ? TruncSFloat64 : TruncSFloat32; // imprecise, because this wasm thing might trap, while asm.js never would
+ ret->type = WasmType::i32;
+ return ret;
+ } else {
+ // WebAssembly traps on float-to-int overflows, but asm.js wouldn't, so we must emulate that
+ CallImport *ret = allocator.alloc<CallImport>();
+ ret->target = F64_TO_INT;
+ auto input = process(ast[2][2]);
+ if (input->type == f32) {
+ auto conv = allocator.alloc<Unary>();
+ conv->op = PromoteFloat32;
+ conv->value = input;
+ conv->type = WasmType::f64;
+ input = conv;
+ }
+ ret->operands.push_back(input);
+ ret->type = i32;
+ static bool addedImport = false;
+ if (!addedImport) {
+ addedImport = true;
+ auto import = allocator.alloc<Import>(); // f64-to-int = asm2wasm.f64-to-int;
+ import->name = F64_TO_INT;
+ import->module = ASM2WASM;
+ import->base = F64_TO_INT;
+ import->type = ensureFunctionType("id", &wasm, allocator);
+ wasm.addImport(import);
+ }
+ return ret;
}
- return ret;
}
// no bitwise unary not, so do xor with -1
auto ret = allocator.alloc<Binary>();