diff options
-rw-r--r-- | src/asm2wasm.h | 23 | ||||
-rw-r--r-- | test/unit.asm.js | 7 | ||||
-rw-r--r-- | test/unit.fromasm | 12 |
3 files changed, 39 insertions, 3 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 353f80413..1aca26e88 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -204,8 +204,9 @@ private: // uses, in the first pass std::map<IString, FunctionType> importedFunctionTypes; + std::map<IString, std::vector<CallImport*>> importedFunctionCalls; - void noteImportedFunctionCall(Ref ast, WasmType resultType, AsmData *asmData) { + void noteImportedFunctionCall(Ref ast, WasmType resultType, AsmData *asmData, CallImport* call) { assert(ast[0] == CALL && ast[1][0] == NAME); IString importName = ast[1][1]->getIString(); FunctionType type; @@ -242,6 +243,7 @@ private: } else { importedFunctionTypes[importName] = type; } + importedFunctionCalls[importName].push_back(call); } FunctionType* getFunctionType(Ref parent, ExpressionList& operands) { @@ -670,6 +672,20 @@ void Asm2WasmBuilder::processAsm(Ref ast) { wasm.removeImport(curr); } + // fill out call_import - add extra params as needed. asm tolerates ffi overloading, wasm does not + for (auto& pair : importedFunctionCalls) { + IString name = pair.first; + auto& list = pair.second; + auto type = importedFunctionTypes[name]; + for (auto* call : list) { + for (size_t i = call->operands.size(); i < type.params.size(); i++) { + auto val = allocator.alloc<Const>(); + val->type = val->value.type = type.params[i]; + call->operands.push_back(val); + } + } + } + // finalize indirect calls for (auto& pair : callIndirects) { @@ -1148,8 +1164,9 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { if (wasm.importsMap.find(name) != wasm.importsMap.end()) { Ref parent = astStackHelper.getParent(); WasmType type = !!parent ? detectWasmType(parent, &asmData) : none; - ret = allocator.alloc<CallImport>(); - noteImportedFunctionCall(ast, type, &asmData); + auto specific = allocator.alloc<CallImport>(); + noteImportedFunctionCall(ast, type, &asmData, specific); + ret = specific; } else { ret = allocator.alloc<Call>(); } diff --git a/test/unit.asm.js b/test/unit.asm.js index 491f90835..b9c878613 100644 --- a/test/unit.asm.js +++ b/test/unit.asm.js @@ -8,6 +8,8 @@ function asm() { var Math_abs = global.Math.abs; var Math_ceil = global.Math.ceil; + var abort = env.abort; + function big_negative() { var temp = 0.0; temp = +-2147483648; @@ -143,6 +145,11 @@ function asm() { temp = Math_fround(Math_ceil(B)); temp = Math_fround(u * Math_fround(Math_ceil(Math_fround(B)))); } + function aborts() { + abort(); + abort(55); + abort(); + } function z() { } diff --git a/test/unit.fromasm b/test/unit.fromasm index 83376be39..67cf23f11 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -4,6 +4,7 @@ (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)) (import $f64-to-int "asm2wasm" "f64-to-int" (param f64) (result i32)) (import $f64-rem "asm2wasm" "f64-rem" (param f64 f64) (result f64)) (export "big_negative" $big_negative) @@ -446,6 +447,17 @@ ) ) ) + (func $aborts + (call_import $abort + (i32.const 0) + ) + (call_import $abort + (i32.const 55) + ) + (call_import $abort + (i32.const 0) + ) + ) (func $z (nop) ) |