diff options
author | Frank Emrich <git@emrich.io> | 2024-01-11 21:22:43 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-11 13:22:43 -0800 |
commit | b4dee3dc05834ada8bf94e3e925186bc8b430c30 (patch) | |
tree | 19d3150e7438803274c1dfc03be56dff83309fe7 /src/wasm/wasm.cpp | |
parent | e5948a939eb6610f1cb7742df8c54f6d17389b83 (diff) | |
download | binaryen-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.cpp | 50 |
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(); } |