diff options
-rw-r--r-- | src/asm2wasm.h | 27 | ||||
-rw-r--r-- | test/unit.asm.js | 2 | ||||
-rw-r--r-- | test/unit.fromasm | 19 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 19 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise.no-opts | 19 | ||||
-rw-r--r-- | test/unit.fromasm.no-opts | 19 |
6 files changed, 83 insertions, 22 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index fd250694b..994342b4e 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -244,11 +244,15 @@ private: previous.print(std::cout, 0) << ".\n"; #endif if (*type != *previous) { - // merge it in. we'll add on extra 0 parameters for ones not actually used, etc. + // merge it in. we'll add on extra 0 parameters for ones not actually used, and upgrade types to + // double where there is a conflict (which is ok since in JS, double can contain everything + // i32 and f32 can). for (size_t i = 0; i < type->params.size(); i++) { if (previous->params.size() > i) { if (previous->params[i] == none) { previous->params[i] = type->params[i]; // use a more concrete type + } else if (previous->params[i] != type->params[i]) { + previous->params[i] = f64; // overloaded type, make it a double } } else { previous->params.push_back(type->params[i]); // add a new param @@ -753,14 +757,25 @@ void Asm2WasmBuilder::processAsm(Ref ast) { FinalizeCalls(Asm2WasmBuilder* parent) : parent(parent) {} void visitCallImport(CallImport* curr) { - // fill out call_import - add extra params as needed. asm tolerates ffi overloading, wasm does not + // fill out call_import - add extra params as needed, etc. asm tolerates ffi overloading, wasm does not auto iter = parent->importedFunctionTypes.find(curr->target); if (iter == parent->importedFunctionTypes.end()) return; // one of our fake imports for callIndirect fixups auto type = iter->second.get(); - for (size_t i = curr->operands.size(); i < type->params.size(); i++) { - auto val = parent->allocator.alloc<Const>(); - val->type = val->value.type = type->params[i]; - curr->operands.push_back(val); + for (size_t i = 0; i < type->params.size(); i++) { + if (i >= curr->operands.size()) { + // add a new param + auto val = parent->allocator.alloc<Const>(); + val->type = val->value.type = type->params[i]; + curr->operands.push_back(val); + } else if (curr->operands[i]->type != type->params[i]) { + assert(type->params[i] == f64); + // overloaded, upgrade to f64 + switch (curr->operands[i]->type) { + case i32: curr->operands[i] = parent->builder.makeUnary(ConvertSInt32ToFloat64, curr->operands[i]); break; + case f32: curr->operands[i] = parent->builder.makeUnary(PromoteFloat32, curr->operands[i]); break; + default: {} // f64, unreachable, etc., are all good + } + } } } void visitCallIndirect(CallIndirect* curr) { diff --git a/test/unit.asm.js b/test/unit.asm.js index b0e4e7594..380c97b41 100644 --- a/test/unit.asm.js +++ b/test/unit.asm.js @@ -194,6 +194,8 @@ function asm(global, env, buffer) { abort(); abort(55); abort(); + abort(12.34); + abort(Math_fround(56.78)); } function continues() { while (1) { diff --git a/test/unit.fromasm b/test/unit.fromasm index 6939b9138..e5b08cdf5 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -5,7 +5,8 @@ (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vi (func (param i32))) - (import $abort "env" "abort" (param i32)) + (type $FUNCSIG$vd (func (param f64))) + (import $abort "env" "abort" (param f64)) (import $print "env" "print" (param i32)) (import $h "env" "h" (param i32)) (import $f64-to-int "asm2wasm" "f64-to-int" (param f64) (result i32)) @@ -303,13 +304,23 @@ ) (func $aborts (call_import $abort - (i32.const 0) + (f64.const 0) ) (call_import $abort - (i32.const 55) + (f64.convert_s/i32 + (i32.const 55) + ) + ) + (call_import $abort + (f64.const 0) ) (call_import $abort - (i32.const 0) + (f64.const 12.34) + ) + (call_import $abort + (f64.promote/f32 + (f32.const 56.779998779296875) + ) ) ) (func $continues diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index ba8dae715..1ee3b88ea 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -4,7 +4,8 @@ (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vi (func (param i32))) - (import $abort "env" "abort" (param i32)) + (type $FUNCSIG$vd (func (param f64))) + (import $abort "env" "abort" (param f64)) (import $print "env" "print" (param i32)) (import $h "env" "h" (param i32)) (import $f64-rem "asm2wasm" "f64-rem" (param f64 f64) (result f64)) @@ -295,13 +296,23 @@ ) (func $aborts (call_import $abort - (i32.const 0) + (f64.const 0) ) (call_import $abort - (i32.const 55) + (f64.convert_s/i32 + (i32.const 55) + ) + ) + (call_import $abort + (f64.const 0) ) (call_import $abort - (i32.const 0) + (f64.const 12.34) + ) + (call_import $abort + (f64.promote/f32 + (f32.const 56.779998779296875) + ) ) ) (func $continues diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index 9f49824f3..4fa627938 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -4,7 +4,8 @@ (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vi (func (param i32))) - (import $abort "env" "abort" (param i32)) + (type $FUNCSIG$vd (func (param f64))) + (import $abort "env" "abort" (param f64)) (import $print "env" "print" (param i32)) (import $h "env" "h" (param i32)) (import $f64-rem "asm2wasm" "f64-rem" (param f64 f64) (result f64)) @@ -515,13 +516,23 @@ ) (func $aborts (call_import $abort - (i32.const 0) + (f64.const 0) ) (call_import $abort - (i32.const 55) + (f64.convert_s/i32 + (i32.const 55) + ) ) (call_import $abort - (i32.const 0) + (f64.const 0) + ) + (call_import $abort + (f64.const 12.34) + ) + (call_import $abort + (f64.promote/f32 + (f32.const 56.779998779296875) + ) ) ) (func $continues diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index ccf89c5b6..e4338b657 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -5,7 +5,8 @@ (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vi (func (param i32))) - (import $abort "env" "abort" (param i32)) + (type $FUNCSIG$vd (func (param f64))) + (import $abort "env" "abort" (param f64)) (import $print "env" "print" (param i32)) (import $h "env" "h" (param i32)) (import $f64-to-int "asm2wasm" "f64-to-int" (param f64) (result i32)) @@ -519,13 +520,23 @@ ) (func $aborts (call_import $abort - (i32.const 0) + (f64.const 0) ) (call_import $abort - (i32.const 55) + (f64.convert_s/i32 + (i32.const 55) + ) ) (call_import $abort - (i32.const 0) + (f64.const 0) + ) + (call_import $abort + (f64.const 12.34) + ) + (call_import $abort + (f64.promote/f32 + (f32.const 56.779998779296875) + ) ) ) (func $continues |