summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asm2wasm.h27
-rw-r--r--test/unit.asm.js2
-rw-r--r--test/unit.fromasm19
-rw-r--r--test/unit.fromasm.imprecise19
-rw-r--r--test/unit.fromasm.imprecise.no-opts19
-rw-r--r--test/unit.fromasm.no-opts19
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