diff options
author | Alon Zakai <azakai@google.com> | 2021-01-27 17:46:31 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-27 09:46:31 -0800 |
commit | 2bdc4841b680ee44e132bbb07f5167eaa7226f99 (patch) | |
tree | 170585bbb9c74022201efeeee91962fdb5f0a1f1 /src/wasm-interpreter.h | |
parent | f82e94363a231bf570fbe3d7dc49259c8668206f (diff) | |
download | binaryen-2bdc4841b680ee44e132bbb07f5167eaa7226f99.tar.gz binaryen-2bdc4841b680ee44e132bbb07f5167eaa7226f99.tar.bz2 binaryen-2bdc4841b680ee44e132bbb07f5167eaa7226f99.zip |
[GC] ref.as_* (#3520)
These are similar to is, but instead of returning an i32 answer, they trap on
an invalid value, and return it otherwise.
These could in theory be in a single RefDoThing, with opcodes for both As
and Is, but as the return values are different, that would be a little odd, and
the name would be less clear.
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r-- | src/wasm-interpreter.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index e8716efbc..ab5644bf4 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1635,6 +1635,38 @@ public: } return Literal(int32_t(data->values.size())); } + Flow visitRefAs(RefAs* curr) { + NOTE_ENTER("RefAs"); + Flow flow = visit(curr->value); + if (flow.breaking()) { + return flow; + } + const auto& value = flow.getSingleValue(); + NOTE_EVAL1(value); + if (value.isNull()) { + trap("null ref"); + } + switch (curr->op) { + case RefAsFunc: + if (value.type.isFunction()) { + trap("not a func"); + } + break; + case RefAsData: + if (value.isGCData()) { + trap("not a data"); + } + break; + case RefAsI31: + if (value.type.getHeapType() != HeapType::i31) { + trap("not an i31"); + } + break; + default: + WASM_UNREACHABLE("unimplemented ref.is_*"); + } + return value; + } virtual void trap(const char* why) { WASM_UNREACHABLE("unimp"); } |