@@ -1963,53 +1963,52 @@ Result<> IRBuilder::makeSuspend(Name tag) {
1963
1963
return Ok{};
1964
1964
}
1965
1965
1966
- static std::vector<Type>
1967
- computeResumeTableSentTypes (Module& wasm,
1968
- const Signature& contSig,
1969
- const std::vector<Name>& handlerTags,
1970
- const std::vector<Name> handlerBlocks) {
1971
- assert (handlerBlocks.size () == handlerTags.size ());
1972
-
1973
- // Let $tag be a tag with type [tgp*] -> [tgr*]. Let $ct be a continuation
1974
- // type (cont $ft), where $ft is [ctp*] -> [ctr*]. Then an instruction
1975
- // (resume $ct ... (tag $tag $block) ... ) causes $block to receive values
1976
- // of the following types when suspending to $tag: tgp* (ref $ct') where ct'
1977
- // = (cont $ft') and ft' = [tgr*] -> [ctr*].
1978
- //
1966
+ struct ResumeTable {
1967
+ std::vector<Name> targets;
1979
1968
std::vector<Type> sentTypes;
1980
- sentTypes.reserve (handlerTags.size ());
1981
- auto & ctrs = contSig.params ;
1982
- for (Index i = 0 ; i < handlerTags.size (); i++) {
1983
- Type sentType;
1984
- if (handlerBlocks[i].isNull ()) {
1985
- sentType = Type::none;
1986
- } else {
1987
- auto & tag = handlerTags[i];
1988
- auto & tagSig = wasm.getTag (tag)->sig ;
1989
-
1990
- auto & tgps = tagSig.params ;
1991
- auto & tgrs = tagSig.results ;
1969
+ };
1992
1970
1993
- HeapType ftPrime{Signature (tgrs, ctrs)};
1994
- HeapType ctPrime{Continuation (ftPrime)};
1995
- Type ctPrimeRef (ctPrime, Nullability::NonNullable);
1971
+ static Result<ResumeTable>
1972
+ makeResumeTable (const std::vector<std::optional<Index>>& labels,
1973
+ std::function<Result<Name>(Index)> getLabelName,
1974
+ std::function<Result<Type>(Index)> getLabelType) {
1975
+ std::vector<Name> targets;
1976
+ targets.reserve (labels.size ());
1996
1977
1997
- if (tgps.size () > 0 ) {
1998
- TypeList sentValueTypes;
1999
- sentValueTypes.reserve (tgps.size () + 1 );
1978
+ std::vector<Type> sentTypes;
1979
+ sentTypes.reserve (sentTypes.size ());
2000
1980
2001
- sentValueTypes.insert (sentValueTypes.begin (), tgps.begin (), tgps.end ());
2002
- sentValueTypes.push_back (ctPrimeRef);
2003
- sentType = Type (sentValueTypes);
1981
+ for (Index i = 0 ; i < labels.size (); i++) {
1982
+ Name target;
1983
+ Type sentType;
1984
+ if (labels[i].has_value ()) {
1985
+ // (on $tag $label) clause
1986
+ Index labelIndex = labels[i].value ();
1987
+ Result<Name> name = getLabelName (labelIndex);
1988
+ CHECK_ERR (name);
1989
+ target = *name;
1990
+
1991
+ Result<Type> targetType = getLabelType (labelIndex);
1992
+ CHECK_ERR (targetType);
1993
+ if (targetType->isContinuation ()) {
1994
+ sentType = *targetType;
1995
+ } else if (targetType->isTuple () &&
1996
+ targetType->getTuple ().back ().isContinuation ()) {
1997
+ // The continuation type is expected to be the last element of
1998
+ // a multi-valued block.
1999
+ sentType = *targetType;
2004
2000
} else {
2005
- sentType = ctPrimeRef ;
2001
+ return Err{ " expected continuation type " } ;
2006
2002
}
2003
+ } else {
2004
+ // (on $tag switch) clause
2005
+ target = Name ();
2006
+ sentType = Type::none;
2007
2007
}
2008
+ targets.push_back (target);
2008
2009
sentTypes.push_back (sentType);
2009
2010
}
2010
- assert (sentTypes.size () == handlerTags.size () &&
2011
- sentTypes.size () == handlerBlocks.size ());
2012
- return sentTypes;
2011
+ return ResumeTable{std::move (targets), std::move (sentTypes)};
2013
2012
}
2014
2013
2015
2014
Result<>
@@ -2025,24 +2024,18 @@ IRBuilder::makeResume(HeapType ct,
2025
2024
curr.operands .resize (contSig.params .size ());
2026
2025
CHECK_ERR (visitResume (&curr));
2027
2026
2028
- std::vector<Name> labelNames;
2029
- labelNames.reserve (labels.size ());
2030
- for (size_t i = 0 ; i < labels.size (); i++) {
2031
- if (labels[i].has_value ()) {
2032
- auto name = getLabelName (labels[i].value ());
2033
- CHECK_ERR (name);
2034
- labelNames.push_back (*name);
2035
- } else {
2036
- labelNames.push_back (Name ());
2037
- }
2038
- }
2039
- std::vector<Type> sentTypes =
2040
- computeResumeTableSentTypes (wasm, contSig, tags, labelNames);
2041
- curr.sentTypes .resize (sentTypes.size ());
2042
- assert (sentTypes.size () == labelNames.size ());
2027
+ Result<ResumeTable> resumetable = std::move (makeResumeTable (
2028
+ labels,
2029
+ [this ](Index i) { return this ->getLabelName (i); },
2030
+ [this ](Index i) { return this ->getLabelType (i); }));
2031
+ CHECK_ERR (resumetable);
2043
2032
std::vector<Expression*> operands (curr.operands .begin (), curr.operands .end ());
2044
- push (
2045
- builder.makeResume (ct, tags, labelNames, sentTypes, operands, curr.cont ));
2033
+ push (builder.makeResume (ct,
2034
+ tags,
2035
+ resumetable->targets ,
2036
+ resumetable->sentTypes ,
2037
+ operands,
2038
+ curr.cont ));
2046
2039
return Ok{};
2047
2040
}
2048
2041
@@ -2058,29 +2051,25 @@ IRBuilder::makeResumeThrow(HeapType ct,
2058
2051
return Err{" expected continuation type" };
2059
2052
}
2060
2053
ResumeThrow curr (wasm.allocator );
2061
- auto contSig = ct.getContinuation ().type .getSignature ();
2062
2054
curr.contType = ct;
2063
2055
curr.tag = tag;
2064
2056
curr.operands .resize (wasm.getTag (tag)->sig .params .size ());
2065
2057
CHECK_ERR (visitResumeThrow (&curr));
2066
2058
2067
- std::vector<Name> labelNames;
2068
- labelNames.reserve (labels.size ());
2069
- for (size_t i = 0 ; i < labels.size (); i++) {
2070
- if (labels[i].has_value ()) {
2071
- auto name = getLabelName (labels[i].value ());
2072
- CHECK_ERR (name);
2073
- labelNames.push_back (*name);
2074
- } else {
2075
- labelNames.push_back (Name ());
2076
- }
2077
- }
2078
- std::vector<Type> sentTypes =
2079
- computeResumeTableSentTypes (wasm, contSig, tags, labelNames);
2059
+ Result<ResumeTable> resumetable = std::move (makeResumeTable (
2060
+ labels,
2061
+ [this ](Index i) { return this ->getLabelName (i); },
2062
+ [this ](Index i) { return this ->getLabelType (i); }));
2063
+ CHECK_ERR (resumetable);
2080
2064
2081
2065
std::vector<Expression*> operands (curr.operands .begin (), curr.operands .end ());
2082
- push (builder.makeResumeThrow (
2083
- ct, tag, tags, labelNames, sentTypes, operands, curr.cont ));
2066
+ push (builder.makeResumeThrow (ct,
2067
+ tag,
2068
+ tags,
2069
+ resumetable->targets ,
2070
+ resumetable->sentTypes ,
2071
+ operands,
2072
+ curr.cont ));
2084
2073
return Ok{};
2085
2074
}
2086
2075
0 commit comments