summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/binaryen-c.cpp186
-rw-r--r--src/binaryen-c.h122
-rw-r--r--test/example/c-api-kitchen-sink.c164
-rw-r--r--test/example/c-api-kitchen-sink.txt29
4 files changed, 501 insertions, 0 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index e827392c0..f7e8142f1 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -239,6 +239,37 @@ BinaryenPackedType BinaryenPackedTypeInt16(void) {
// Heap types
+BinaryenHeapType BinaryenHeapTypeFunc() {
+ return static_cast<BinaryenHeapType>(HeapType::BasicHeapType::func);
+}
+BinaryenHeapType BinaryenHeapTypeAny() {
+ return static_cast<BinaryenHeapType>(HeapType::BasicHeapType::any);
+}
+BinaryenHeapType BinaryenHeapTypeEq() {
+ return static_cast<BinaryenHeapType>(HeapType::BasicHeapType::eq);
+}
+BinaryenHeapType BinaryenHeapTypeI31() {
+ return static_cast<BinaryenHeapType>(HeapType::BasicHeapType::i31);
+}
+BinaryenHeapType BinaryenHeapTypeData() {
+ return static_cast<BinaryenHeapType>(HeapType::BasicHeapType::data);
+}
+BinaryenHeapType BinaryenHeapTypeString() {
+ return static_cast<BinaryenHeapType>(HeapType::BasicHeapType::string);
+}
+BinaryenHeapType BinaryenHeapTypeStringviewWTF8() {
+ return static_cast<BinaryenHeapType>(
+ HeapType::BasicHeapType::stringview_wtf8);
+}
+BinaryenHeapType BinaryenHeapTypeStringviewWTF16() {
+ return static_cast<BinaryenHeapType>(
+ HeapType::BasicHeapType::stringview_wtf16);
+}
+BinaryenHeapType BinaryenHeapTypeStringviewIter() {
+ return static_cast<BinaryenHeapType>(
+ HeapType::BasicHeapType::stringview_iter);
+}
+
BinaryenHeapType BinaryenTypeGetHeapType(BinaryenType type) {
return Type(type).getHeapType().getID();
}
@@ -4781,6 +4812,161 @@ ExpressionRunnerRunAndDispose(ExpressionRunnerRef runner,
}
//
+// ========= Type builder =========
+//
+
+TypeBuilderErrorReason TypeBuilderErrorReasonSelfSupertype() {
+ return static_cast<TypeBuilderErrorReason>(
+ TypeBuilder::ErrorReason::SelfSupertype);
+}
+TypeBuilderErrorReason TypeBuilderErrorReasonInvalidSupertype() {
+ return static_cast<TypeBuilderErrorReason>(
+ TypeBuilder::ErrorReason::InvalidSupertype);
+}
+TypeBuilderErrorReason TypeBuilderErrorReasonForwardSupertypeReference() {
+ return static_cast<TypeBuilderErrorReason>(
+ TypeBuilder::ErrorReason::ForwardSupertypeReference);
+}
+TypeBuilderErrorReason TypeBuilderErrorReasonForwardChildReference() {
+ return static_cast<TypeBuilderErrorReason>(
+ TypeBuilder::ErrorReason::ForwardChildReference);
+}
+
+TypeBuilderRef TypeBuilderCreate(BinaryenIndex size) {
+ return static_cast<TypeBuilderRef>(new TypeBuilder(size));
+}
+void TypeBuilderGrow(TypeBuilderRef builder, BinaryenIndex count) {
+ ((TypeBuilder*)builder)->grow(count);
+}
+BinaryenIndex TypeBuilderGetSize(TypeBuilderRef builder) {
+ return ((TypeBuilder*)builder)->size();
+}
+void TypeBuilderSetBasicHeapType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenBasicHeapType basicHeapType) {
+ ((TypeBuilder*)builder)
+ ->setHeapType(index, HeapType::BasicHeapType(basicHeapType));
+}
+void TypeBuilderSetSignatureType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenType paramTypes,
+ BinaryenType resultTypes) {
+ ((TypeBuilder*)builder)
+ ->setHeapType(index, Signature(Type(paramTypes), Type(resultTypes)));
+}
+void TypeBuilderSetStructType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenType* fieldTypes,
+ BinaryenPackedType* fieldPackedTypes,
+ bool* fieldMutables,
+ int numFields) {
+ auto* B = (TypeBuilder*)builder;
+ FieldList fields;
+ for (int cur = 0; cur < numFields; ++cur) {
+ Field field(Type(fieldTypes[cur]),
+ fieldMutables[cur] ? Mutability::Mutable
+ : Mutability::Immutable);
+ if (field.type == Type::i32) {
+ field.packedType = Field::PackedType(fieldPackedTypes[cur]);
+ } else {
+ assert(fieldPackedTypes[cur] == Field::PackedType::not_packed);
+ }
+ fields.push_back(field);
+ }
+ B->setHeapType(index, Struct(fields));
+}
+void TypeBuilderSetArrayType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenType elementType,
+ BinaryenPackedType elementPackedType,
+ int elementMutable) {
+ auto* B = (TypeBuilder*)builder;
+ Field element(Type(elementType),
+ elementMutable ? Mutability::Mutable : Mutability::Immutable);
+ if (element.type == Type::i32) {
+ element.packedType = Field::PackedType(elementPackedType);
+ } else {
+ assert(elementPackedType == Field::PackedType::not_packed);
+ }
+ B->setHeapType(index, Array(element));
+}
+bool TypeBuilderIsBasic(TypeBuilderRef builder, BinaryenIndex index) {
+ return ((TypeBuilder*)builder)->isBasic(index);
+}
+BinaryenBasicHeapType TypeBuilderGetBasic(TypeBuilderRef builder,
+ BinaryenIndex index) {
+ return BinaryenBasicHeapType(((TypeBuilder*)builder)->getBasic(index));
+}
+BinaryenHeapType TypeBuilderGetTempHeapType(TypeBuilderRef builder,
+ BinaryenIndex index) {
+ return ((TypeBuilder*)builder)->getTempHeapType(index).getID();
+}
+BinaryenType TypeBuilderGetTempTupleType(TypeBuilderRef builder,
+ BinaryenType* types,
+ BinaryenIndex numTypes) {
+ TypeList typeList(numTypes);
+ for (BinaryenIndex cur = 0; cur < numTypes; ++cur) {
+ typeList[cur] = Type(types[cur]);
+ }
+ return ((TypeBuilder*)builder)->getTempTupleType(Tuple(typeList)).getID();
+}
+BinaryenType TypeBuilderGetTempRttType(TypeBuilderRef builder,
+ BinaryenIndex depth,
+ BinaryenHeapType heapType) {
+ return ((TypeBuilder*)builder)
+ ->getTempRttType(Rtt(depth, HeapType(heapType)))
+ .getID();
+}
+BinaryenType TypeBuilderGetTempRefType(TypeBuilderRef builder,
+ BinaryenHeapType heapType,
+ int nullable) {
+ return ((TypeBuilder*)builder)
+ ->getTempRefType(HeapType(heapType), nullable ? Nullable : NonNullable)
+ .getID();
+}
+void TypeBuilderSetSubType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenIndex superIndex) {
+ ((TypeBuilder*)builder)->setSubType(index, superIndex);
+}
+void TypeBuilderCreateRecGroup(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenIndex length) {
+ ((TypeBuilder*)builder)->createRecGroup(index, length);
+}
+bool TypeBuilderBuildAndDispose(TypeBuilderRef builder,
+ BinaryenHeapType* heapTypes,
+ BinaryenIndex* errorIndex,
+ TypeBuilderErrorReason* errorReason) {
+ auto* B = (TypeBuilder*)builder;
+ auto result = B->build();
+ if (auto err = result.getError()) {
+ *errorIndex = err->index;
+ *errorReason = static_cast<TypeBuilderErrorReason>(err->reason);
+ delete B;
+ return false;
+ }
+ auto types = *result;
+ for (size_t cur = 0; cur < types.size(); ++cur) {
+ heapTypes[cur] = types[cur].getID();
+ }
+ delete B;
+ return true;
+}
+
+void BinaryenModuleSetTypeName(BinaryenModuleRef module,
+ BinaryenHeapType heapType,
+ const char* name) {
+ ((Module*)module)->typeNames[HeapType(heapType)].name = name;
+}
+void BinaryenModuleSetFieldName(BinaryenModuleRef module,
+ BinaryenHeapType heapType,
+ BinaryenIndex index,
+ const char* name) {
+ ((Module*)module)->typeNames[HeapType(heapType)].fieldNames[index] = name;
+}
+
+//
// ========= Utilities =========
//
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index 4f74eef4e..6a2222f71 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -137,6 +137,16 @@ BINARYEN_API BinaryenPackedType BinaryenPackedTypeInt16(void);
typedef uintptr_t BinaryenHeapType;
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeFunc(void);
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeAny(void);
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeEq(void);
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeI31(void);
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeData(void);
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeString(void);
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeStringviewWTF8(void);
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeStringviewWTF16(void);
+BINARYEN_API BinaryenHeapType BinaryenHeapTypeStringviewIter(void);
+
BINARYEN_API BinaryenHeapType BinaryenTypeGetHeapType(BinaryenType type);
BINARYEN_API bool BinaryenTypeIsNullable(BinaryenType type);
BINARYEN_API BinaryenType BinaryenTypeFromHeapType(BinaryenHeapType heapType,
@@ -2896,6 +2906,118 @@ BINARYEN_API BinaryenExpressionRef ExpressionRunnerRunAndDispose(
ExpressionRunnerRef runner, BinaryenExpressionRef expr);
//
+// ========= TypeBuilder =========
+//
+
+#ifdef __cplusplus
+namespace wasm {
+struct TypeBuilder;
+} // namespace wasm
+typedef struct wasm::TypeBuilder* TypeBuilderRef;
+#else
+typedef struct TypeBuilder* TypeBuilderRef;
+#endif
+
+typedef uint32_t TypeBuilderErrorReason;
+
+// Indicates a cycle in the supertype relation.
+BINARYEN_API TypeBuilderErrorReason TypeBuilderErrorReasonSelfSupertype(void);
+// Indicates that the declared supertype of a type is invalid.
+BINARYEN_API TypeBuilderErrorReason
+TypeBuilderErrorReasonInvalidSupertype(void);
+// Indicates that the declared supertype is an invalid forward reference.
+BINARYEN_API TypeBuilderErrorReason
+TypeBuilderErrorReasonForwardSupertypeReference(void);
+// Indicates that a child of a type is an invalid forward reference.
+BINARYEN_API TypeBuilderErrorReason
+TypeBuilderErrorReasonForwardChildReference(void);
+
+typedef uint32_t BinaryenBasicHeapType;
+
+// Constructs a new type builder that allows for the construction of recursive
+// types. Contains a table of `size` mutable heap types.
+BINARYEN_API TypeBuilderRef TypeBuilderCreate(BinaryenIndex size);
+// Grows the backing table of the type builder by `count` slots.
+BINARYEN_API void TypeBuilderGrow(TypeBuilderRef builder, BinaryenIndex count);
+// Gets the size of the backing table of the type builder.
+BINARYEN_API BinaryenIndex TypeBuilderGetSize(TypeBuilderRef builder);
+// Sets the heap type at index `index` to a basic heap type. Must not be used in
+// nominal mode.
+BINARYEN_API void
+TypeBuilderSetBasicHeapType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenBasicHeapType basicHeapType);
+// Sets the heap type at index `index` to a concrete signature type. Expects
+// temporary tuple types if multiple parameter and/or result types include
+// temporary types.
+BINARYEN_API void TypeBuilderSetSignatureType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenType paramTypes,
+ BinaryenType resultTypes);
+// Sets the heap type at index `index` to a concrete struct type.
+BINARYEN_API void TypeBuilderSetStructType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenType* fieldTypes,
+ BinaryenPackedType* fieldPackedTypes,
+ bool* fieldMutables,
+ int numFields);
+// Sets the heap type at index `index` to a concrete array type.
+BINARYEN_API void TypeBuilderSetArrayType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenType elementType,
+ BinaryenPackedType elementPackedType,
+ int elementMutable);
+// Tests if the heap type at index `index` is a basic heap type.
+BINARYEN_API bool TypeBuilderIsBasic(TypeBuilderRef builder,
+ BinaryenIndex index);
+// Gets the basic heap type at index `index`.
+BINARYEN_API BinaryenBasicHeapType TypeBuilderGetBasic(TypeBuilderRef builder,
+ BinaryenIndex index);
+// Gets the temporary heap type to use at index `index`. Temporary heap types
+// may only be used to construct temporary types using the type builder.
+BINARYEN_API BinaryenHeapType TypeBuilderGetTempHeapType(TypeBuilderRef builder,
+ BinaryenIndex index);
+// Gets a temporary tuple type for use with and owned by the type builder.
+BINARYEN_API BinaryenType TypeBuilderGetTempTupleType(TypeBuilderRef builder,
+ BinaryenType* types,
+ BinaryenIndex numTypes);
+// Gets a temporary reference type for use with and owned by the type builder.
+BINARYEN_API BinaryenType TypeBuilderGetTempRefType(TypeBuilderRef builder,
+ BinaryenHeapType heapType,
+ int nullable);
+// Gets a temporary RTT for use with and owned by the type builder.
+BINARYEN_API BinaryenType TypeBuilderGetTempRttType(TypeBuilderRef builder,
+ BinaryenIndex depth,
+ BinaryenHeapType heapType);
+// Sets the type at `index` to be a subtype of the type at `superIndex`.
+BINARYEN_API void TypeBuilderSetSubType(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenIndex superIndex);
+// Creates a new recursion group in the range `index` inclusive to `index +
+// length` exclusive. Recursion groups must not overlap.
+BINARYEN_API void TypeBuilderCreateRecGroup(TypeBuilderRef builder,
+ BinaryenIndex index,
+ BinaryenIndex length);
+// Builds the heap type hierarchy and disposes the builder. Returns `false` and
+// populates `errorIndex` and `errorReason` on failure.
+BINARYEN_API bool
+TypeBuilderBuildAndDispose(TypeBuilderRef builder,
+ BinaryenHeapType* heapTypes,
+ BinaryenIndex* errorIndex,
+ TypeBuilderErrorReason* errorReason);
+
+// Sets the textual name of a compound `heapType`. Has no effect if the type
+// already has a canonical name.
+BINARYEN_API void BinaryenModuleSetTypeName(BinaryenModuleRef module,
+ BinaryenHeapType heapType,
+ const char* name);
+// Sets the field name of a struct `heapType` at index `index`.
+BINARYEN_API void BinaryenModuleSetFieldName(BinaryenModuleRef module,
+ BinaryenHeapType heapType,
+ BinaryenIndex index,
+ const char* name);
+
+//
// ========= Utilities =========
//
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index 54446711a..dab64522a 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -318,7 +318,21 @@ void test_types() {
BinaryenPackedType i16 = BinaryenPackedTypeInt16();
printf("BinaryenPackedTypeInt16: %d\n", i16);
+ printf("BinaryenHeapTypeFunc: %zd\n", BinaryenHeapTypeFunc());
+ printf("BinaryenHeapTypeAny: %zd\n", BinaryenHeapTypeAny());
+ printf("BinaryenHeapTypeEq: %zd\n", BinaryenHeapTypeEq());
+ printf("BinaryenHeapTypeI31: %zd\n", BinaryenHeapTypeI31());
+ printf("BinaryenHeapTypeData: %zd\n", BinaryenHeapTypeData());
+ printf("BinaryenHeapTypeString: %zd\n", BinaryenHeapTypeString());
+ printf("BinaryenHeapTypeStringviewWTF8: %zd\n",
+ BinaryenHeapTypeStringviewWTF8());
+ printf("BinaryenHeapTypeStringviewWTF16: %zd\n",
+ BinaryenHeapTypeStringviewWTF16());
+ printf("BinaryenHeapTypeStringviewIter: %zd\n",
+ BinaryenHeapTypeStringviewIter());
+
BinaryenHeapType eq = BinaryenTypeGetHeapType(eqref);
+ assert(eq == BinaryenHeapTypeEq());
BinaryenType ref_null_eq = BinaryenTypeFromHeapType(eq, true);
assert(BinaryenTypeGetHeapType(ref_null_eq) == eq);
assert(BinaryenTypeIsNullable(ref_null_eq));
@@ -1747,6 +1761,155 @@ void test_typesystem() {
BinaryenSetTypeSystem(defaultTypeSystem);
}
+void test_typebuilder() {
+ BinaryenTypeSystem defaultTypeSystem = BinaryenGetTypeSystem();
+ BinaryenSetTypeSystem(BinaryenTypeSystemIsorecursive());
+
+ printf("TypeBuilderErrorReasonSelfSupertype: %d\n",
+ TypeBuilderErrorReasonSelfSupertype());
+ printf("TypeBuilderErrorReasonInvalidSupertype: %d\n",
+ TypeBuilderErrorReasonInvalidSupertype());
+ printf("TypeBuilderErrorReasonForwardSupertypeReference: %d\n",
+ TypeBuilderErrorReasonForwardSupertypeReference());
+ printf("TypeBuilderErrorReasonForwardChildReference: %d\n",
+ TypeBuilderErrorReasonForwardChildReference());
+
+ TypeBuilderRef builder = TypeBuilderCreate(0);
+ assert(TypeBuilderGetSize(builder) == 0);
+ TypeBuilderGrow(builder, 5);
+ assert(TypeBuilderGetSize(builder) == 5);
+
+ // Create a recursive array of its own type
+ const BinaryenIndex tempArrayIndex = 0;
+ BinaryenHeapType tempArrayHeapType =
+ TypeBuilderGetTempHeapType(builder, tempArrayIndex);
+ BinaryenType tempArrayType =
+ TypeBuilderGetTempRefType(builder, tempArrayHeapType, true);
+ TypeBuilderSetArrayType(builder,
+ tempArrayIndex,
+ tempArrayType,
+ BinaryenPackedTypeNotPacked(),
+ true);
+
+ // Create a recursive struct with a field of its own type
+ const BinaryenIndex tempStructIndex = 1;
+ BinaryenHeapType tempStructHeapType =
+ TypeBuilderGetTempHeapType(builder, tempStructIndex);
+ BinaryenType tempStructType =
+ TypeBuilderGetTempRefType(builder, tempStructHeapType, true);
+ {
+ BinaryenType fieldTypes[] = {tempStructType};
+ BinaryenPackedType fieldPackedTypes[] = {BinaryenPackedTypeNotPacked()};
+ bool fieldMutables[] = {true};
+ TypeBuilderSetStructType(
+ builder, tempStructIndex, fieldTypes, fieldPackedTypes, fieldMutables, 1);
+ }
+
+ // Create a recursive signature with parameter and result including its own
+ // type
+ const BinaryenIndex tempSignatureIndex = 2;
+ BinaryenHeapType tempSignatureHeapType =
+ TypeBuilderGetTempHeapType(builder, tempSignatureIndex);
+ BinaryenType tempSignatureType =
+ TypeBuilderGetTempRefType(builder, tempSignatureHeapType, true);
+ {
+ BinaryenType paramTypes[] = {tempSignatureType, tempArrayType};
+ TypeBuilderSetSignatureType(
+ builder,
+ tempSignatureIndex,
+ TypeBuilderGetTempTupleType(builder, &paramTypes, 2),
+ tempSignatureType);
+ }
+
+ // Create a basic heap type
+ const BinaryenIndex tempBasicIndex = 3;
+ TypeBuilderSetBasicHeapType(
+ builder, 3, BinaryenTypeGetHeapType(BinaryenTypeEqref()));
+ assert(TypeBuilderIsBasic(builder, tempBasicIndex));
+ assert(TypeBuilderGetBasic(builder, tempBasicIndex) ==
+ BinaryenTypeGetHeapType(BinaryenTypeEqref()));
+ assert(!TypeBuilderIsBasic(builder, tempArrayIndex));
+ assert(!TypeBuilderIsBasic(builder, tempStructIndex));
+ assert(!TypeBuilderIsBasic(builder, tempSignatureIndex));
+
+ // Create a subtype (with an additional packed field)
+ const BinaryenIndex tempSubStructIndex = 4;
+ BinaryenHeapType tempSubStructHeapType =
+ TypeBuilderGetTempHeapType(builder, tempSubStructIndex);
+ BinaryenType tempSubStructType =
+ TypeBuilderGetTempRefType(builder, tempSubStructHeapType, true);
+ {
+ BinaryenType fieldTypes[] = {
+ tempStructType, BinaryenTypeInt32()}; // must repeat existing fields
+ BinaryenPackedType fieldPackedTypes[] = {BinaryenPackedTypeNotPacked(),
+ BinaryenPackedTypeInt8()};
+ bool fieldMutables[] = {true, true};
+ TypeBuilderSetStructType(builder,
+ tempSubStructIndex,
+ fieldTypes,
+ fieldPackedTypes,
+ fieldMutables,
+ 2);
+ }
+ TypeBuilderSetSubType(builder, tempSubStructIndex, tempStructIndex);
+
+ // TODO: Rtts (post-MVP?)
+
+ // Build the type hierarchy and dispose the builder
+ BinaryenHeapType heapTypes[5];
+ BinaryenIndex errorIndex;
+ TypeBuilderErrorReason errorReason;
+ bool didBuildAndDispose = TypeBuilderBuildAndDispose(
+ builder, (BinaryenHeapType*)&heapTypes, &errorIndex, &errorReason);
+ assert(didBuildAndDispose);
+ BinaryenType arrayType =
+ BinaryenTypeFromHeapType(heapTypes[tempArrayIndex], true);
+ BinaryenType structType =
+ BinaryenTypeFromHeapType(heapTypes[tempStructIndex], true);
+ BinaryenType signatureType =
+ BinaryenTypeFromHeapType(heapTypes[tempSignatureIndex], true);
+ BinaryenType basicType =
+ BinaryenTypeFromHeapType(heapTypes[tempBasicIndex], true);
+ BinaryenType subStructType =
+ BinaryenTypeFromHeapType(heapTypes[tempSubStructIndex], true);
+
+ // Build a simple test module, validate and print it
+ BinaryenModuleRef module = BinaryenModuleCreate();
+ BinaryenModuleSetTypeName(module, heapTypes[tempArrayIndex], "SomeArray");
+ BinaryenModuleSetTypeName(module, heapTypes[tempStructIndex], "SomeStruct");
+ BinaryenModuleSetFieldName(
+ module, heapTypes[tempStructIndex], 0, "SomeField");
+ BinaryenModuleSetTypeName(
+ module, heapTypes[tempSignatureIndex], "SomeSignature");
+ BinaryenModuleSetTypeName(module, heapTypes[tempBasicIndex], "does-nothing");
+ BinaryenModuleSetTypeName(
+ module, heapTypes[tempSubStructIndex], "SomeSubStruct");
+ BinaryenModuleSetFieldName(
+ module, heapTypes[tempSubStructIndex], 0, "SomeField");
+ BinaryenModuleSetFieldName(
+ module, heapTypes[tempSubStructIndex], 1, "SomePackedField");
+ BinaryenModuleSetFeatures(
+ module, BinaryenFeatureReferenceTypes() | BinaryenFeatureGC());
+ {
+ BinaryenType varTypes[] = {
+ arrayType, structType, signatureType, basicType, subStructType};
+ BinaryenAddFunction(module,
+ "test",
+ BinaryenNone(),
+ BinaryenNone(),
+ varTypes,
+ 5,
+ BinaryenNop(module));
+ }
+ bool didValidate = BinaryenModuleValidate(module);
+ assert(didValidate);
+ printf("module with recursive GC types:\n");
+ BinaryenModulePrint(module);
+ BinaryenModuleDispose(module);
+
+ BinaryenSetTypeSystem(defaultTypeSystem);
+}
+
int main() {
test_types();
test_features();
@@ -1760,6 +1923,7 @@ int main() {
test_for_each();
test_func_opt();
test_typesystem();
+ test_typebuilder();
return 0;
}
diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt
index 518e8ea5e..ff71e08e5 100644
--- a/test/example/c-api-kitchen-sink.txt
+++ b/test/example/c-api-kitchen-sink.txt
@@ -19,6 +19,15 @@ BinaryenTypeAuto: -1
BinaryenPackedTypeNotPacked: 0
BinaryenPackedTypeInt8: 1
BinaryenPackedTypeInt16: 2
+BinaryenHeapTypeFunc: 0
+BinaryenHeapTypeAny: 1
+BinaryenHeapTypeEq: 2
+BinaryenHeapTypeI31: 3
+BinaryenHeapTypeData: 4
+BinaryenHeapTypeString: 5
+BinaryenHeapTypeStringviewWTF8: 6
+BinaryenHeapTypeStringviewWTF16: 7
+BinaryenHeapTypeStringviewIter: 8
BinaryenFeatureMVP: 0
BinaryenFeatureAtomics: 1
BinaryenFeatureBulkMemory: 16
@@ -2710,3 +2719,23 @@ optimized:
BinaryenTypeSystemEquirecursive: 0
BinaryenTypeSystemNominal: 1
BinaryenTypeSystemIsorecursive: 2
+TypeBuilderErrorReasonSelfSupertype: 0
+TypeBuilderErrorReasonInvalidSupertype: 1
+TypeBuilderErrorReasonForwardSupertypeReference: 2
+TypeBuilderErrorReasonForwardChildReference: 3
+module with recursive GC types:
+(module
+ (type $SomeArray (array_subtype (mut (ref null $SomeArray)) data))
+ (type $SomeStruct (struct_subtype (field $SomeField (mut (ref null $SomeStruct))) data))
+ (type $SomeSignature (func_subtype (param (ref null $SomeSignature) (ref null $SomeArray)) (result (ref null $SomeSignature)) func))
+ (type $none_=>_none (func_subtype func))
+ (type $SomeSubStruct (struct_subtype (field $SomeField (mut (ref null $SomeStruct))) (field $SomePackedField (mut i8)) $SomeStruct))
+ (func $test (type $none_=>_none)
+ (local $0 (ref null $SomeArray))
+ (local $1 (ref null $SomeStruct))
+ (local $2 (ref null $SomeSignature))
+ (local $3 eqref)
+ (local $4 (ref null $SomeSubStruct))
+ (nop)
+ )
+)