@@ -387,6 +387,56 @@ public let WasmCodeGenerators: [CodeGenerator] = [
387387 )
388388 } ,
389389
390+ CodeGenerator (
391+ " WasmRefCastGenerator " , inContext: . single( . wasmFunction) ,
392+ inputs: . requiredComplex( . init( . wasmTypeDef( ) ) ) ,
393+ produces: [ . wasmGenericRef]
394+ ) { b, typeDef in
395+ guard let abstractType =
396+ b. type ( of: typeDef) . wasmTypeDefinition? . description? . abstractHeapSupertype? . heapType
397+ as? WasmAbstractHeapType
398+ else { fatalError ( " Invalid type description for \( b. type ( of: typeDef) ) " ) }
399+ let function = b. currentWasmModule. currentWasmFunction
400+ let variable = switch abstractType {
401+ case . WasmFunc, . WasmNoFunc:
402+ function. findOrGenerateWasmVar ( ofType: . wasmFuncRef( ) )
403+ case . WasmArray, . WasmStruct:
404+ function. findOrGenerateWasmVar ( ofType: . wasmAnyRef( ) )
405+ default :
406+ fatalError ( " The type \( abstractType) shouldn't have a definition " )
407+ }
408+ let refType = ILType . wasmRef ( . Index( ) , nullability: Bool . random ( ) )
409+ function. wasmRefCast ( variable, refType: refType, typeDef: typeDef)
410+ } ,
411+
412+ CodeGenerator (
413+ " WasmRefCastAbstractGenerator " , inContext: . single( . wasmFunction) ,
414+ inputs: . required( . wasmGenericRef) ,
415+ produces: [ . wasmGenericRef]
416+ ) { b, ref in
417+ let function = b. currentWasmModule. currentWasmFunction
418+ let heapType = switch b. type ( of: ref) . wasmReferenceType!. kind {
419+ case . Abstract( let heapTypeInfo) :
420+ heapTypeInfo. heapType
421+ case . Index( let desc) :
422+ desc. get ( ) !. abstractHeapSupertype!. heapType
423+ }
424+ let incompatible : [ WasmAbstractHeapType ] = [ . WasmStruct, . WasmArray, . WasmI31]
425+ let chosenType = chooseUniform (
426+ from: WasmAbstractHeapType . allCases. filter {
427+ $0 != heapType &&
428+ $0. inSameHierarchy ( heapType) &&
429+ ( // 90% of the time it won't contain two incompatible types
430+ probability ( 0.1 ) ||
431+ !( incompatible. contains ( $0) && incompatible. contains ( heapType) )
432+ )
433+ }
434+ )
435+ // TODO(pawkra): add shared variant.
436+ let newType = ILType . wasmRef ( . Abstract( HeapTypeInfo ( chosenType, shared: false ) ) , nullability: Bool . random ( ) )
437+ function. wasmRefCast ( ref, refType: newType)
438+ } ,
439+
390440 // Primitive Value Generators
391441
392442 CodeGenerator (
0 commit comments