summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-01-27 17:46:31 +0000
committerGitHub <noreply@github.com>2021-01-27 09:46:31 -0800
commit2bdc4841b680ee44e132bbb07f5167eaa7226f99 (patch)
tree170585bbb9c74022201efeeee91962fdb5f0a1f1 /src/wasm-interpreter.h
parentf82e94363a231bf570fbe3d7dc49259c8668206f (diff)
downloadbinaryen-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.h32
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"); }