summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-05-04 17:20:13 -0700
committerGitHub <noreply@github.com>2023-05-05 00:20:13 +0000
commit879d7bfb0fcd8335892677fd6d24a2f02218a6c2 (patch)
treec32785d40ba673d96ffb32a23e3ccc437b277503 /src
parent7f8e4cbf6273c9b13b3a1a42f5e2833ea0d0f686 (diff)
downloadbinaryen-879d7bfb0fcd8335892677fd6d24a2f02218a6c2.tar.gz
binaryen-879d7bfb0fcd8335892677fd6d24a2f02218a6c2.tar.bz2
binaryen-879d7bfb0fcd8335892677fd6d24a2f02218a6c2.zip
[NFC] Track the kinds of items that names refer to in wasm-delegations-fields (#5690)
This makes delegations-fields track Kinds. That is, rather than say a field is just a Name, we can say it is a name of kind Function. This allows users to track references to functions, tables, memories, etc., in a simple and generic way, avoiding duplicated code which we have atm. (In particular this will help wasm-merge in the future.) This also uses that functionality in two small places to show the benefits (see memory-utils.cpp and MemoryPacking.cpp).
Diffstat (limited to 'src')
-rw-r--r--src/ir/memory-utils.cpp34
-rw-r--r--src/passes/MemoryPacking.cpp41
-rw-r--r--src/passes/RemoveUnusedModuleElements.cpp1
-rw-r--r--src/wasm-delegations-fields.def92
-rw-r--r--src/wasm.h15
5 files changed, 135 insertions, 48 deletions
diff --git a/src/ir/memory-utils.cpp b/src/ir/memory-utils.cpp
index 49ec25529..1530e7c11 100644
--- a/src/ir/memory-utils.cpp
+++ b/src/ir/memory-utils.cpp
@@ -27,7 +27,8 @@ bool flatten(Module& wasm) {
// The presence of any instruction that cares about segment identity is a
// problem because flattening gets rid of that (when it merges them all into
// one big segment).
- struct Scanner : public WalkerPass<PostWalker<Scanner>> {
+ struct Scanner : public WalkerPass<
+ PostWalker<Scanner, UnifiedExpressionVisitor<Scanner>>> {
std::atomic<bool>& noticesSegmentIdentity;
Scanner(std::atomic<bool>& noticesSegmentIdentity)
@@ -37,10 +38,33 @@ bool flatten(Module& wasm) {
return std::make_unique<Scanner>(noticesSegmentIdentity);
}
- void visitMemoryInit(MemoryInit* curr) { noticesSegmentIdentity = true; }
- void visitDataDrop(DataDrop* curr) { noticesSegmentIdentity = true; }
- void visitArrayNewData(ArrayNewData* curr) {
- noticesSegmentIdentity = true;
+ void visitExpression(Expression* curr) {
+#define DELEGATE_ID curr->_id
+
+#define DELEGATE_START(id) [[maybe_unused]] auto* cast = curr->cast<id>();
+
+#define DELEGATE_GET_FIELD(id, field) cast->field
+
+#define DELEGATE_FIELD_TYPE(id, field)
+#define DELEGATE_FIELD_HEAPTYPE(id, field)
+#define DELEGATE_FIELD_CHILD(id, field)
+#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field)
+#define DELEGATE_FIELD_INT(id, field)
+#define DELEGATE_FIELD_INT_ARRAY(id, field)
+#define DELEGATE_FIELD_LITERAL(id, field)
+#define DELEGATE_FIELD_NAME(id, field)
+#define DELEGATE_FIELD_NAME_VECTOR(id, field)
+#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
+#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
+#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field)
+#define DELEGATE_FIELD_ADDRESS(id, field)
+
+#define DELEGATE_FIELD_NAME_KIND(id, field, kind) \
+ if (kind == ModuleItemKind::DataSegment) { \
+ noticesSegmentIdentity = true; \
+ }
+
+#include "wasm-delegations-fields.def"
}
};
diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp
index 08d1407f4..5f72a916d 100644
--- a/src/passes/MemoryPacking.cpp
+++ b/src/passes/MemoryPacking.cpp
@@ -464,21 +464,38 @@ void MemoryPacking::getSegmentReferrers(Module* module,
if (func->imported()) {
return;
}
- struct Collector : WalkerPass<PostWalker<Collector>> {
+ struct Collector
+ : WalkerPass<PostWalker<Collector, UnifiedExpressionVisitor<Collector>>> {
ReferrersMap& referrers;
Collector(ReferrersMap& referrers) : referrers(referrers) {}
- void visitMemoryInit(MemoryInit* curr) {
- referrers[curr->segment].push_back(curr);
- }
- void visitDataDrop(DataDrop* curr) {
- referrers[curr->segment].push_back(curr);
- }
- void visitArrayNewData(ArrayNewData* curr) {
- referrers[curr->segment].push_back(curr);
- }
- void visitArrayInitData(ArrayInitData* curr) {
- referrers[curr->segment].push_back(curr);
+ void visitExpression(Expression* curr) {
+#define DELEGATE_ID curr->_id
+
+#define DELEGATE_START(id) [[maybe_unused]] auto* cast = curr->cast<id>();
+
+#define DELEGATE_GET_FIELD(id, field) cast->field
+
+#define DELEGATE_FIELD_TYPE(id, field)
+#define DELEGATE_FIELD_HEAPTYPE(id, field)
+#define DELEGATE_FIELD_CHILD(id, field)
+#define DELEGATE_FIELD_OPTIONAL_CHILD(id, field)
+#define DELEGATE_FIELD_INT(id, field)
+#define DELEGATE_FIELD_INT_ARRAY(id, field)
+#define DELEGATE_FIELD_LITERAL(id, field)
+#define DELEGATE_FIELD_NAME(id, field)
+#define DELEGATE_FIELD_NAME_VECTOR(id, field)
+#define DELEGATE_FIELD_SCOPE_NAME_DEF(id, field)
+#define DELEGATE_FIELD_SCOPE_NAME_USE(id, field)
+#define DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR(id, field)
+#define DELEGATE_FIELD_ADDRESS(id, field)
+
+#define DELEGATE_FIELD_NAME_KIND(id, field, kind) \
+ if (kind == ModuleItemKind::DataSegment) { \
+ referrers[cast->field].push_back(curr); \
+ }
+
+#include "wasm-delegations-fields.def"
}
} collector(referrers);
collector.walkFunctionInModule(func, module);
diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp
index 725e292b2..25b5ea9e9 100644
--- a/src/passes/RemoveUnusedModuleElements.cpp
+++ b/src/passes/RemoveUnusedModuleElements.cpp
@@ -203,6 +203,7 @@ struct ReferenceFinder : public PostWalker<ReferenceFinder> {
auto type = curr->ref->type.getHeapType();
note(StructField{type, curr->index});
}
+ // TODO: use delegations-fields
void visitArrayNewData(ArrayNewData* curr) {
note({ModuleElementKind::DataSegment, curr->segment});
}
diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def
index 4398ee5e3..1d9d6244d 100644
--- a/src/wasm-delegations-fields.def
+++ b/src/wasm-delegations-fields.def
@@ -72,6 +72,17 @@
// and DELEGATE_GET_FIELD is, then DELEGATE_FIELD_SCOPE_NAME_USE is called on
// them.
//
+// DELEGATE_FIELD_NAME_KIND(id, field, kind) - called for a field that contains
+// the name of a ModuleItemKind (i.e., a top-level module entity like a table
+// or a function). If this is not defined then DELEGATE_FIELD_NAME is called
+// instead.
+//
+// DELEGATE_FIELD_NAME_KIND_VECTOR(id, field, kind) - called for a variable-
+// sized vector of DELEGATE_FIELD_NAME_KIND. If this is not defined, and
+// DELEGATE_GET_FIELD is, then DELEGATE_FIELD_NAME_KIND is called on them.
+// Or, if this is not defined by DELEGATE_FIELD_NAME_VECTOR is, then that is
+// called.
+//
// DELEGATE_FIELD_TYPE(id, field) - called for a Type.
//
// DELEGATE_FIELD_HEAPTYPE(id, field) - called for a HeapType.
@@ -158,6 +169,23 @@
#endif
#endif
+#ifndef DELEGATE_FIELD_NAME_KIND
+#define DELEGATE_FIELD_NAME_KIND(id, field, kind) \
+ DELEGATE_FIELD_NAME(id, field);
+#endif
+
+#ifndef DELEGATE_FIELD_NAME_KIND_VECTOR
+#ifdef DELEGATE_GET_FIELD
+#define DELEGATE_FIELD_NAME_KIND_VECTOR(id, field, kind) \
+ for (Index i = 0; i < (DELEGATE_GET_FIELD(id, field)).size(); i++) { \
+ DELEGATE_FIELD_NAME_KIND(id, field[i], kind); \
+ }
+#else
+#define DELEGATE_FIELD_NAME_KIND_VECTOR(id, field, kind) \
+ DELEGATE_FIELD_NAME_VECTOR(id, field)
+#endif
+#endif
+
#ifndef DELEGATE_FIELD_TYPE
#error please define DELEGATE_FIELD_TYPE(id, field)
#endif
@@ -217,7 +245,7 @@ switch (DELEGATE_ID) {
case Expression::Id::CallId: {
DELEGATE_START(Call);
DELEGATE_FIELD_CHILD_VECTOR(Call, operands);
- DELEGATE_FIELD_NAME(Call, target);
+ DELEGATE_FIELD_NAME_KIND(Call, target, ModuleItemKind::Function);
DELEGATE_FIELD_INT(Call, isReturn);
DELEGATE_END(Call);
break;
@@ -225,7 +253,7 @@ switch (DELEGATE_ID) {
case Expression::Id::CallIndirectId: {
DELEGATE_START(CallIndirect);
DELEGATE_FIELD_CHILD(CallIndirect, target);
- DELEGATE_FIELD_NAME(CallIndirect, table);
+ DELEGATE_FIELD_NAME_KIND(CallIndirect, table, ModuleItemKind::Table);
DELEGATE_FIELD_CHILD_VECTOR(CallIndirect, operands);
DELEGATE_FIELD_HEAPTYPE(CallIndirect, heapType);
DELEGATE_FIELD_INT(CallIndirect, isReturn);
@@ -247,14 +275,14 @@ switch (DELEGATE_ID) {
}
case Expression::Id::GlobalGetId: {
DELEGATE_START(GlobalGet);
- DELEGATE_FIELD_INT(GlobalGet, name);
+ DELEGATE_FIELD_NAME_KIND(GlobalGet, name, ModuleItemKind::Global);
DELEGATE_END(GlobalGet);
break;
}
case Expression::Id::GlobalSetId: {
DELEGATE_START(GlobalSet);
DELEGATE_FIELD_CHILD(GlobalSet, value);
- DELEGATE_FIELD_INT(GlobalSet, name);
+ DELEGATE_FIELD_NAME_KIND(GlobalSet, name, ModuleItemKind::Global);
DELEGATE_END(GlobalSet);
break;
}
@@ -266,7 +294,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_ADDRESS(Load, offset);
DELEGATE_FIELD_ADDRESS(Load, align);
DELEGATE_FIELD_INT(Load, isAtomic);
- DELEGATE_FIELD_NAME(Load, memory);
+ DELEGATE_FIELD_NAME_KIND(Load, memory, ModuleItemKind::Memory);
DELEGATE_END(Load);
break;
}
@@ -279,7 +307,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_ADDRESS(Store, align);
DELEGATE_FIELD_INT(Store, isAtomic);
DELEGATE_FIELD_TYPE(Store, valueType);
- DELEGATE_FIELD_NAME(Store, memory);
+ DELEGATE_FIELD_NAME_KIND(Store, memory, ModuleItemKind::Memory);
DELEGATE_END(Store);
break;
}
@@ -290,7 +318,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_INT(AtomicRMW, op);
DELEGATE_FIELD_INT(AtomicRMW, bytes);
DELEGATE_FIELD_ADDRESS(AtomicRMW, offset);
- DELEGATE_FIELD_NAME(AtomicRMW, memory);
+ DELEGATE_FIELD_NAME_KIND(AtomicRMW, memory, ModuleItemKind::Memory);
DELEGATE_END(AtomicRMW);
break;
}
@@ -301,7 +329,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_CHILD(AtomicCmpxchg, ptr);
DELEGATE_FIELD_INT(AtomicCmpxchg, bytes);
DELEGATE_FIELD_ADDRESS(AtomicCmpxchg, offset);
- DELEGATE_FIELD_NAME(AtomicCmpxchg, memory);
+ DELEGATE_FIELD_NAME_KIND(AtomicCmpxchg, memory, ModuleItemKind::Memory);
DELEGATE_END(AtomicCmpxchg);
break;
}
@@ -312,7 +340,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_CHILD(AtomicWait, ptr);
DELEGATE_FIELD_ADDRESS(AtomicWait, offset);
DELEGATE_FIELD_TYPE(AtomicWait, expectedType);
- DELEGATE_FIELD_NAME(AtomicWait, memory);
+ DELEGATE_FIELD_NAME_KIND(AtomicWait, memory, ModuleItemKind::Memory);
DELEGATE_END(AtomicWait);
break;
}
@@ -321,7 +349,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_CHILD(AtomicNotify, notifyCount);
DELEGATE_FIELD_CHILD(AtomicNotify, ptr);
DELEGATE_FIELD_ADDRESS(AtomicNotify, offset);
- DELEGATE_FIELD_NAME(AtomicNotify, memory);
+ DELEGATE_FIELD_NAME_KIND(AtomicNotify, memory, ModuleItemKind::Memory);
DELEGATE_END(AtomicNotify);
break;
}
@@ -379,7 +407,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_INT(SIMDLoad, op);
DELEGATE_FIELD_ADDRESS(SIMDLoad, offset);
DELEGATE_FIELD_ADDRESS(SIMDLoad, align);
- DELEGATE_FIELD_NAME(SIMDLoad, memory);
+ DELEGATE_FIELD_NAME_KIND(SIMDLoad, memory, ModuleItemKind::Memory);
DELEGATE_END(SIMDLoad);
break;
}
@@ -391,7 +419,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_ADDRESS(SIMDLoadStoreLane, offset);
DELEGATE_FIELD_ADDRESS(SIMDLoadStoreLane, align);
DELEGATE_FIELD_INT(SIMDLoadStoreLane, index);
- DELEGATE_FIELD_NAME(SIMDLoadStoreLane, memory);
+ DELEGATE_FIELD_NAME_KIND(SIMDLoadStoreLane, memory, ModuleItemKind::Memory);
DELEGATE_END(SIMDLoadStoreLane);
break;
}
@@ -400,14 +428,14 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_CHILD(MemoryInit, size);
DELEGATE_FIELD_CHILD(MemoryInit, offset);
DELEGATE_FIELD_CHILD(MemoryInit, dest);
- DELEGATE_FIELD_NAME(MemoryInit, segment);
- DELEGATE_FIELD_NAME(MemoryInit, memory);
+ DELEGATE_FIELD_NAME_KIND(MemoryInit, segment, ModuleItemKind::DataSegment);
+ DELEGATE_FIELD_NAME_KIND(MemoryInit, memory, ModuleItemKind::Memory);
DELEGATE_END(MemoryInit);
break;
}
case Expression::Id::DataDropId: {
DELEGATE_START(DataDrop);
- DELEGATE_FIELD_NAME(DataDrop, segment);
+ DELEGATE_FIELD_NAME_KIND(DataDrop, segment, ModuleItemKind::DataSegment);
DELEGATE_END(DataDrop);
break;
}
@@ -416,8 +444,8 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_CHILD(MemoryCopy, size);
DELEGATE_FIELD_CHILD(MemoryCopy, source);
DELEGATE_FIELD_CHILD(MemoryCopy, dest);
- DELEGATE_FIELD_NAME(MemoryCopy, sourceMemory);
- DELEGATE_FIELD_NAME(MemoryCopy, destMemory);
+ DELEGATE_FIELD_NAME_KIND(MemoryCopy, sourceMemory, ModuleItemKind::Memory);
+ DELEGATE_FIELD_NAME_KIND(MemoryCopy, destMemory, ModuleItemKind::Memory);
DELEGATE_END(MemoryCopy);
break;
}
@@ -426,7 +454,7 @@ switch (DELEGATE_ID) {
DELEGATE_FIELD_CHILD(MemoryFill, size);
DELEGATE_FIELD_CHILD(MemoryFill, value);
DELEGATE_FIELD_CHILD(MemoryFill, dest);
- DELEGATE_FIELD_NAME(MemoryFill, memory);
+ DELEGATE_FIELD_NAME_KIND(MemoryFill, memory, ModuleItemKind::Memory);
DELEGATE_END(MemoryFill);
break;
}
@@ -474,7 +502,7 @@ switch (DELEGATE_ID) {
case Expression::Id::MemorySizeId: {
DELEGATE_START(MemorySize);
DELEGATE_FIELD_TYPE(MemorySize, ptrType);
- DELEGATE_FIELD_NAME(MemorySize, memory);
+ DELEGATE_FIELD_NAME_KIND(MemorySize, memory, ModuleItemKind::Memory);
DELEGATE_END(MemorySize);
break;
}
@@ -482,7 +510,7 @@ switch (DELEGATE_ID) {
DELEGATE_START(MemoryGrow);
DELEGATE_FIELD_TYPE(MemoryGrow, ptrType);
DELEGATE_FIELD_CHILD(MemoryGrow, delta);
- DELEGATE_FIELD_NAME(MemoryGrow, memory);
+ DELEGATE_FIELD_NAME_KIND(MemoryGrow, memory, ModuleItemKind::Memory);
DELEGATE_END(MemoryGrow);
break;
}
@@ -499,7 +527,7 @@ switch (DELEGATE_ID) {
}
case Expression::Id::RefFuncId: {
DELEGATE_START(RefFunc);
- DELEGATE_FIELD_NAME(RefFunc, func);
+ DELEGATE_FIELD_NAME_KIND(RefFunc, func, ModuleItemKind::Function);
DELEGATE_END(RefFunc);
break;
}
@@ -513,7 +541,7 @@ switch (DELEGATE_ID) {
case Expression::Id::TableGetId: {
DELEGATE_START(TableGet);
DELEGATE_FIELD_CHILD(TableGet, index);
- DELEGATE_FIELD_NAME(TableGet, table);
+ DELEGATE_FIELD_NAME_KIND(TableGet, table, ModuleItemKind::Table);
DELEGATE_END(TableGet);
break;
}
@@ -521,13 +549,13 @@ switch (DELEGATE_ID) {
DELEGATE_START(TableSet);
DELEGATE_FIELD_CHILD(TableSet, value);
DELEGATE_FIELD_CHILD(TableSet, index);
- DELEGATE_FIELD_NAME(TableSet, table);
+ DELEGATE_FIELD_NAME_KIND(TableSet, table, ModuleItemKind::Table);
DELEGATE_END(TableSet);
break;
}
case Expression::Id::TableSizeId: {
DELEGATE_START(TableSize);
- DELEGATE_FIELD_NAME(TableSize, table);
+ DELEGATE_FIELD_NAME_KIND(TableSize, table, ModuleItemKind::Table);
DELEGATE_END(TableSize);
break;
}
@@ -535,7 +563,7 @@ switch (DELEGATE_ID) {
DELEGATE_START(TableGrow);
DELEGATE_FIELD_CHILD(TableGrow, delta);
DELEGATE_FIELD_CHILD(TableGrow, value);
- DELEGATE_FIELD_NAME(TableGrow, table);
+ DELEGATE_FIELD_NAME_KIND(TableGrow, table, ModuleItemKind::Table);
DELEGATE_END(TableGrow);
break;
}
@@ -543,7 +571,7 @@ switch (DELEGATE_ID) {
DELEGATE_START(Try);
DELEGATE_FIELD_SCOPE_NAME_USE(Try, delegateTarget);
DELEGATE_FIELD_CHILD_VECTOR(Try, catchBodies);
- DELEGATE_FIELD_NAME_VECTOR(Try, catchTags);
+ DELEGATE_FIELD_NAME_KIND_VECTOR(Try, catchTags, ModuleItemKind::Tag);
DELEGATE_FIELD_SCOPE_NAME_DEF(Try, name);
DELEGATE_FIELD_CHILD(Try, body);
DELEGATE_END(Try);
@@ -552,7 +580,7 @@ switch (DELEGATE_ID) {
case Expression::Id::ThrowId: {
DELEGATE_START(Throw);
DELEGATE_FIELD_CHILD_VECTOR(Throw, operands);
- DELEGATE_FIELD_NAME(Throw, tag);
+ DELEGATE_FIELD_NAME_KIND(Throw, tag, ModuleItemKind::Tag);
DELEGATE_END(Throw);
break;
}
@@ -665,7 +693,7 @@ switch (DELEGATE_ID) {
}
case Expression::Id::ArrayNewDataId: {
DELEGATE_START(ArrayNewData);
- DELEGATE_FIELD_NAME(ArrayNewData, segment);
+ DELEGATE_FIELD_NAME_KIND(ArrayNewData, segment, ModuleItemKind::DataSegment);
DELEGATE_FIELD_CHILD(ArrayNewData, size);
DELEGATE_FIELD_CHILD(ArrayNewData, offset);
DELEGATE_END(ArrayNewData);
@@ -673,7 +701,7 @@ switch (DELEGATE_ID) {
}
case Expression::Id::ArrayNewElemId: {
DELEGATE_START(ArrayNewElem);
- DELEGATE_FIELD_NAME(ArrayNewElem, segment);
+ DELEGATE_FIELD_NAME_KIND(ArrayNewElem, segment, ModuleItemKind::ElementSegment);
DELEGATE_FIELD_CHILD(ArrayNewElem, size);
DELEGATE_FIELD_CHILD(ArrayNewElem, offset);
DELEGATE_END(ArrayNewElem);
@@ -728,7 +756,7 @@ switch (DELEGATE_ID) {
}
case Expression::Id::ArrayInitDataId: {
DELEGATE_START(ArrayInitData);
- DELEGATE_FIELD_NAME(ArrayInitData, segment);
+ DELEGATE_FIELD_NAME_KIND(ArrayInitData, segment, ModuleItemKind::DataSegment);
DELEGATE_FIELD_CHILD(ArrayInitData, size);
DELEGATE_FIELD_CHILD(ArrayInitData, offset);
DELEGATE_FIELD_CHILD(ArrayInitData, index);
@@ -738,7 +766,7 @@ switch (DELEGATE_ID) {
}
case Expression::Id::ArrayInitElemId: {
DELEGATE_START(ArrayInitElem);
- DELEGATE_FIELD_NAME(ArrayInitElem, segment);
+ DELEGATE_FIELD_NAME_KIND(ArrayInitElem, segment, ModuleItemKind::ElementSegment);
DELEGATE_FIELD_CHILD(ArrayInitElem, size);
DELEGATE_FIELD_CHILD(ArrayInitElem, offset);
DELEGATE_FIELD_CHILD(ArrayInitElem, index);
@@ -869,6 +897,8 @@ switch (DELEGATE_ID) {
#undef DELEGATE_FIELD_SCOPE_NAME_DEF
#undef DELEGATE_FIELD_SCOPE_NAME_USE
#undef DELEGATE_FIELD_SCOPE_NAME_USE_VECTOR
+#undef DELEGATE_FIELD_NAME_KIND
+#undef DELEGATE_FIELD_NAME_KIND_VECTOR
#undef DELEGATE_FIELD_TYPE
#undef DELEGATE_FIELD_HEAPTYPE
#undef DELEGATE_FIELD_ADDRESS
diff --git a/src/wasm.h b/src/wasm.h
index 825f35099..474497847 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -2068,6 +2068,21 @@ enum class ExternalKind {
Invalid = -1
};
+// The kind of a top-level module item. (This overlaps with ExternalKind, but
+// C++ has no good way to extend an enum.) All such items are referred to by
+// name in the IR (that is, the IR is relocatable), and so they are subclasses
+// of the Named class.
+enum class ModuleItemKind {
+ Function = 0,
+ Table = 1,
+ Memory = 2,
+ Global = 3,
+ Tag = 4,
+ DataSegment = 5,
+ ElementSegment = 6,
+ Invalid = -1
+};
+
class Export {
public:
// exported name - note that this is the key, as the internal name is