diff options
-rw-r--r-- | src/ir/intrinsics.cpp | 10 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 10 | ||||
-rw-r--r-- | test/lit/exec/intrinsics.wast | 24 |
3 files changed, 41 insertions, 3 deletions
diff --git a/src/ir/intrinsics.cpp b/src/ir/intrinsics.cpp index c2318cabf..26b624391 100644 --- a/src/ir/intrinsics.cpp +++ b/src/ir/intrinsics.cpp @@ -19,11 +19,17 @@ namespace wasm { -static Name BinaryenIntrinsics("binaryen-intrinsics"), +static Name BinaryenIntrinsicsModule("binaryen-intrinsics"), CallWithoutEffects("call.without.effects"); bool Intrinsics::isCallWithoutEffects(Function* func) { - return func->module == BinaryenIntrinsics && func->base == CallWithoutEffects; + if (func->module != BinaryenIntrinsicsModule) { + return false; + } + if (func->base == CallWithoutEffects) { + return true; + } + Fatal() << "Unrecognized intrinsic"; } Call* Intrinsics::isCallWithoutEffects(Expression* curr) { diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 107f38f09..65ffdbade 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -28,6 +28,7 @@ #include <sstream> #include <variant> +#include "ir/intrinsics.h" #include "ir/module-utils.h" #include "support/bits.h" #include "support/safe_integer.h" @@ -2757,7 +2758,14 @@ public: } auto* func = wasm.getFunction(curr->target); Flow ret; - if (func->imported()) { + if (Intrinsics(*self()->getModule()).isCallWithoutEffects(func)) { + // The call.without.effects intrinsic is a call to an import that actually + // calls the given function reference that is the final argument. + auto newArguments = arguments; + auto target = newArguments.back(); + newArguments.pop_back(); + ret.values = callFunctionInternal(target.getFunc(), newArguments); + } else if (func->imported()) { ret.values = externalInterface->callImport(func, arguments); } else { ret.values = callFunctionInternal(curr->target, arguments); diff --git a/test/lit/exec/intrinsics.wast b/test/lit/exec/intrinsics.wast new file mode 100644 index 000000000..d53082a77 --- /dev/null +++ b/test/lit/exec/intrinsics.wast @@ -0,0 +1,24 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited. + +;; RUN: wasm-opt %s -all --fuzz-exec-before -q -o /dev/null 2>&1 | filecheck %s + +(module + (import "binaryen-intrinsics" "call.without.effects" (func $cwe (param i32 funcref) (result i32))) + + ;; CHECK: [fuzz-exec] calling get-ref + ;; CHECK-NEXT: [fuzz-exec] note result: get-ref => 42 + (func "get-ref" (result i32) + (call $cwe + (i32.const 41) + (ref.func $add-one) + ) + ) + + (func $add-one (param $x i32) (result i32) + (i32.add + (local.get $x) + (i32.const 1) + ) + ) +) + |