From ffac06650507ac413d60d72aadc1e33fb1f91ccf Mon Sep 17 00:00:00 2001 From: Abbas Mashayekh Date: Wed, 24 Mar 2021 21:43:45 +0430 Subject: [RT] Support expressions in element segments (#3666) This PR adds support for `ref.null t` as a valid element segment item. The abbreviated format of `(elem ... func $f $g...)` is kept in both printing and binary emitting if all items are `ref.func`s. Public APIs aren't updated in this PR. --- src/binaryen-c.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src/binaryen-c.cpp') diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 1b3f11e22..aff4ed4fc 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -3409,7 +3409,13 @@ BinaryenAddActiveElementSegment(BinaryenModuleRef module, auto segment = std::make_unique(table, (Expression*)offset); segment->setExplicitName(name); for (BinaryenIndex i = 0; i < numFuncNames; i++) { - segment->data.push_back(funcNames[i]); + auto* func = ((Module*)module)->getFunctionOrNull(funcNames[i]); + if (func == nullptr) { + Fatal() << "invalid function '" << funcNames[i] << "'."; + } + Type type(HeapType(func->sig), Nullable); + segment->data.push_back( + Builder(*(Module*)module).makeRefFunc(funcNames[i], type)); } return ((Module*)module)->addElementSegment(std::move(segment)); } @@ -3421,7 +3427,13 @@ BinaryenAddPassiveElementSegment(BinaryenModuleRef module, auto segment = std::make_unique(); segment->setExplicitName(name); for (BinaryenIndex i = 0; i < numFuncNames; i++) { - segment->data.push_back(funcNames[i]); + auto* func = ((Module*)module)->getFunctionOrNull(funcNames[i]); + if (func == nullptr) { + Fatal() << "invalid function '" << funcNames[i] << "'."; + } + Type type(HeapType(func->sig), Nullable); + segment->data.push_back( + Builder(*(Module*)module).makeRefFunc(funcNames[i], type)); } return ((Module*)module)->addElementSegment(std::move(segment)); } @@ -3460,7 +3472,13 @@ const char* BinaryenElementSegmentGetData(BinaryenElementSegmentRef elem, if (data.size() <= dataId) { Fatal() << "invalid segment data id."; } - return data[dataId].c_str(); + if (data[dataId]->is()) { + return NULL; + } else if (auto* get = data[dataId]->dynCast()) { + return get->func.c_str(); + } else { + Fatal() << "invalid expression in segment data."; + } } // Memory. One per module -- cgit v1.2.3