diff options
-rw-r--r-- | src/binaryen-c.cpp | 186 | ||||
-rw-r--r-- | src/binaryen-c.h | 122 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 164 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 29 |
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, ¶mTypes, 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) + ) +) |