summaryrefslogtreecommitdiff
path: root/src/wasm/wasm.cpp
diff options
context:
space:
mode:
authorFrank Emrich <git@emrich.io>2024-01-11 21:22:43 +0000
committerGitHub <noreply@github.com>2024-01-11 13:22:43 -0800
commitb4dee3dc05834ada8bf94e3e925186bc8b430c30 (patch)
tree19d3150e7438803274c1dfc03be56dff83309fe7 /src/wasm/wasm.cpp
parente5948a939eb6610f1cb7742df8c54f6d17389b83 (diff)
downloadbinaryen-b4dee3dc05834ada8bf94e3e925186bc8b430c30.tar.gz
binaryen-b4dee3dc05834ada8bf94e3e925186bc8b430c30.tar.bz2
binaryen-b4dee3dc05834ada8bf94e3e925186bc8b430c30.zip
Typed continuations: resume instructions (#6083)
This PR is part of a series that adds basic support for the [typed continuations proposal](https://github.com/wasmfx/specfx). This particular PR adds support for the `resume` instruction. The most notable missing feature is validation, which is not implemented, yet.
Diffstat (limited to 'src/wasm/wasm.cpp')
-rw-r--r--src/wasm/wasm.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index ad44acda4..06e9de148 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -17,6 +17,7 @@
#include "wasm.h"
#include "ir/branch-utils.h"
#include "wasm-traversal.h"
+#include "wasm-type.h"
namespace wasm {
@@ -1350,6 +1351,55 @@ void StringSliceIter::finalize() {
}
}
+static void populateResumeSentTypes(Resume* curr, Module* wasm) {
+ if (!wasm) {
+ return;
+ }
+
+ const Signature& contSig =
+ curr->contType.getContinuation().type.getSignature();
+
+ // Let $tag be a tag with type [tgp*] -> [tgr*]. Let $ct be a continuation
+ // type (cont $ft), where $ft is [ctp*] -> [ctr*]. Then an instruction (resume
+ // $ct ... (tag $tag $block) ... ) causes $block to receive values of the
+ // following types when suspending to $tag: tgp* (ref $ct') where ct' = (cont
+ // $ft') and ft' = [tgr*] -> [ctr*].
+ //
+ auto& ctrs = contSig.results;
+ curr->sentTypes.clear();
+ curr->sentTypes.resize(curr->handlerTags.size());
+ for (Index i = 0; i < curr->handlerTags.size(); i++) {
+ auto& tag = curr->handlerTags[i];
+ auto& tagSig = wasm->getTag(tag)->sig;
+
+ auto& tgps = tagSig.params;
+ auto& tgrs = tagSig.results;
+
+ HeapType ftPrime{Signature(tgrs, ctrs)};
+ HeapType ctPrime{Continuation(ftPrime)};
+ Type ctPrimeRef(ctPrime, Nullability::NonNullable);
+
+ if (tgps.size() > 0) {
+ TypeList sentValueTypes;
+ sentValueTypes.reserve(tgps.size() + 1);
+
+ sentValueTypes.insert(sentValueTypes.begin(), tgps.begin(), tgps.end());
+ sentValueTypes.push_back(ctPrimeRef);
+ curr->sentTypes[i] = Type(sentValueTypes);
+ } else {
+ curr->sentTypes[i] = ctPrimeRef;
+ }
+ }
+}
+
+void Resume::finalize(Module* wasm) {
+ const Signature& contSig =
+ this->contType.getContinuation().type.getSignature();
+ type = contSig.results;
+
+ populateResumeSentTypes(this, wasm);
+}
+
size_t Function::getNumParams() { return getParams().size(); }
size_t Function::getNumVars() { return vars.size(); }