diff options
author | Heejin Ahn <aheejin@gmail.com> | 2020-04-16 19:03:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-16 19:03:55 -0700 |
commit | 727c91af3bc1a317107fbffb0e7bab778dc3f5b6 (patch) | |
tree | 95c56137d76413a6b268d2047a1f6dc54cc7d60a /src/wasm-interpreter.h | |
parent | c9162258a5364f31907786078685b567878c79db (diff) | |
download | binaryen-727c91af3bc1a317107fbffb0e7bab778dc3f5b6.tar.gz binaryen-727c91af3bc1a317107fbffb0e7bab778dc3f5b6.tar.bz2 binaryen-727c91af3bc1a317107fbffb0e7bab778dc3f5b6.zip |
Dummy interpreter support for EH (#2774)
This adds dummy interpreter support for EH instructions, mainly for
fuzzing. The plan is to make the interpreter support for EH instructions
correctly using Asyncify in the future. Also to support the correct
behavior we will need a `Literal` of `exnref` type too, which will be
added later too.
Currently what this dummy implementation does is:
- `try`-`catch`-`end`: only runs `try` body and ignores `catch` body
- `throw`: traps
- `retyrow`:
- Traps on nullref argument (correct behavior based on the spec)
- Traps otherwise too (dummy implementation for now)
- `br_on_exn`:
- Traps on nullref (correct behavior)
- Otherwise we assume the current expression matches the current event
and extracts a 0 literal based on the current type.
This also adds some interpreter tests, which tests the basic dummy
behaviors for now. (Deleted tests are the ones that weren't tested
before.)
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r-- | src/wasm-interpreter.h | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 7a1fc1784..fed58d060 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1215,13 +1215,39 @@ public: NOTE_NAME(curr->func); return Literal::makeFuncref(curr->func); } - // TODO Implement EH instructions - Flow visitTry(Try*) { WASM_UNREACHABLE("unimp"); } - Flow visitThrow(Throw*) { WASM_UNREACHABLE("unimp"); } - Flow visitRethrow(Rethrow*) { WASM_UNREACHABLE("unimp"); } - Flow visitBrOnExn(BrOnExn*) { WASM_UNREACHABLE("unimp"); } + Flow visitTry(Try* curr) { + NOTE_ENTER("Try"); + // FIXME This currently only executes 'try' part. Correctly implement this. + return visit(curr->body); + } + Flow visitThrow(Throw* curr) { + NOTE_ENTER("Throw"); + LiteralList arguments; + Flow flow = generateArguments(curr->operands, arguments); + if (flow.breaking()) { + return flow; + } + NOTE_EVAL1(curr->event); + // FIXME This currently traps. Correctly implement throw. + trap("throw"); + WASM_UNREACHABLE("throw"); + } + Flow visitRethrow(Rethrow* curr) { + NOTE_ENTER("Rethrow"); + Flow flow = visit(curr->exnref); + if (flow.breaking()) { + return flow; + } + if (flow.getType() == Type::nullref) { + trap("rethrow: argument is null"); + } + // FIXME This currently traps. Correctly implement rethrow. + trap("rethrow"); + WASM_UNREACHABLE("rethrow"); + } + Flow visitBrOnExn(BrOnExn* curr) { WASM_UNREACHABLE("unimp"); } - virtual void trap(const char* why) { WASM_UNREACHABLE("unimp"); } + virtual void trap(const char* why) { WASM_UNREACHABLE(why); } }; // Execute an constant expression in a global init or memory offset. @@ -2097,6 +2123,25 @@ private: } return {}; } + Flow visitBrOnExn(BrOnExn* curr) { + NOTE_ENTER("BrOnExn"); + Flow flow = this->visit(curr->exnref); + if (flow.breaking()) { + return flow; + } + if (flow.getType() == Type::nullref) { + trap("br_on_exn: argument is null"); + } + // Currently we don't have a way to tell if the given expression matches + // the given event tag. Assume any exnref matches for now and always + // extracts a zero or null value of the given event type. + // FIXME Correctly implement event matching and extraction. + Type eventType = instance.wasm.getEvent(curr->event)->sig.params; + flow.values = + eventType == Type::none ? Literals() : Literal::makeZero(eventType); + flow.breakTo = curr->name; + return flow; + } Flow visitPush(Push* curr) { NOTE_ENTER("Push"); Flow value = this->visit(curr->value); |