///|
fn gen_valid_dae2_family(profile : GenValidProfile) -> Int32 {
  match profile {
    Dae2CyclesProfile => 1
    Dae2ControlFlowProfile => 2
    Dae2EffectfulArgumentsProfile => 3
    Dae2TupleResultsProfile => 4
    Dae2TailCallsProfile => 5
    Dae2IndirectProfile => 6
    Dae2OpenWorldProfile => 7
    Dae2ReferenceTypesProfile => 8
    Dae2LocalsProfile => 9
    Dae2ContinuationsProfile => 10
    Dae2ExceptionsProfile => 11
    Dae2CallRefProfile => 12
    Dae2IntrinsicsProfile => 13
    _ => 0
  }
}

///|
fn gen_valid_dae2_profile_config(profile : GenValidProfile) -> GenValidConfig {
  let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
  GenValidConfig::{
    ..base,
    features: GenValidFeatureToggles::{
      ..base.features,
      allow_name_custom_sections: profile is Dae2TupleResultsProfile,
    },
    max_type_defs: 12,
    max_imports: 4,
    max_defined_funcs: 12,
    max_tables: 2,
    max_mems: 1,
    max_globals: 2,
    max_tags: 1,
    max_elems: 2,
    max_datas: 0,
    max_params: 4,
    max_results: if profile is Dae2TupleResultsProfile {
      3
    } else {
      2
    },
    max_locals: if profile is Dae2TupleResultsProfile {
      11
    } else {
      8
    },
    max_body_statements: 420 + gen_valid_dae2_family(profile),
    max_body_depth: 12,
  }
}

///|
fn gen_valid_is_dae2_profile_config(config : GenValidConfig) -> Bool {
  for
    profile in [
      Dae2ForwardedResultsProfile,
      Dae2CyclesProfile,
      Dae2ControlFlowProfile,
      Dae2EffectfulArgumentsProfile,
      Dae2TupleResultsProfile,
      Dae2TailCallsProfile,
      Dae2IndirectProfile,
      Dae2OpenWorldProfile,
      Dae2ReferenceTypesProfile,
      Dae2LocalsProfile,
      Dae2ContinuationsProfile,
      Dae2ExceptionsProfile,
      Dae2CallRefProfile,
      Dae2IntrinsicsProfile,
    ] {
    if config == gen_valid_dae2_profile_config(profile) {
      return true
    }
  }
  false
}

///|
fn gen_valid_dae2_profile_module(ctx : GenValidContext) -> Module {
  let family = ctx.config.max_body_statements - 420
  let seed = if ctx.use_named_streams {
    ctx.root_seed
  } else {
    ctx.rnd.next_uint64()
  }
  if family == 4 && ((seed & 15UL) == 8UL || (seed & 15UL) == 9UL) {
    return gen_valid_dae2_overlap_module(
      seed,
      ctx.config.features.allow_name_custom_sections && (seed & 16UL) != 0UL,
    )
  }
  if family == 9 && seed % 12UL == 3UL {
    return gen_valid_dae2_derived_pointer_module(seed)
  }
  if family == 9 && seed % 6UL == 0UL {
    return gen_valid_dae2_inserted_control_module(seed)
  }
  if family == 9 && seed % 3UL != 0UL {
    return gen_valid_dae2_local_state_module(seed, seed % 3UL == 2UL)
  }
  if family == 3 && (seed & 1UL) != 0UL {
    return gen_valid_dae2_pending_memory_module(seed)
  }
  let loop_effect = family == 2 && (seed & 3UL) == 0UL
  let literal = (seed ^ (seed >> 32)).to_int()
  let i32 = ValType::i32()
  let i64 = ValType::i64()
  let get0 = Instruction::local_get(LocalIdx::new(0U))
  let constant = Instruction::i32_const(I32(literal))
  let types : Array[RecType] = []
  let type_indices : Array[TypeIdx] = []
  let bodies : Array[Func] = []
  let add = fn(
    params : Array[ValType],
    results : Array[ValType],
    locals : Array[ValType],
    body : Array[Instruction],
  ) {
    type_indices.push(TypeIdx::new(types.length().reinterpret_as_uint()))
    types.push(
      RecType::new(SubType::comp_type(CompType::func(params, results))),
    )
    bodies.push(Func::new(Locals::from_types(locals), Expr::new(body)))
  }
  let mut module_ = Module::new()
  let counter = GlobalIdx::new(0U)
  let effect = fn(amount : Int32) {
    [
      Instruction::global_get(counter),
      Instruction::i32_const(I32(amount)),
      Instruction::i32_add(),
      Instruction::global_set(counter),
    ]
  }
  if family == 4 || family == 11 || loop_effect {
    module_ = module_.with_global_sec(
      GlobalSec::new([
        Global::new(
          GlobalType::new(i32, true),
          Expr::new([Instruction::i32_const(I32(0))]),
        ),
      ]),
    )
  }
  match family {
    10 => {
      let variant = (seed % 6UL).to_int()
      add([i32], [i32], [], [get0])
      let cont = TypeIdx::new(1U)
      types.push(
        RecType::new(SubType::comp_type(CompType::cont(TypeIdx::new(0U)))),
      )
      let bound_signature = TypeIdx::new(2U)
      types.push(RecType::new(SubType::comp_type(CompType::func([], [i32]))))
      let bound_cont = TypeIdx::new(3U)
      types.push(
        RecType::new(SubType::comp_type(CompType::cont(bound_signature))),
      )
      add([], [i32], [], [constant])
      let tag_signature = TypeIdx::new(5U)
      types.push(
        RecType::new(
          SubType::comp_type(
            CompType::func([], if variant == 3 { [] } else { [i32] }),
          ),
        ),
      )
      let tag = TagIdx::new(0U)
      module_ = module_.with_tag_sec(TagSec::new([TagType::new(tag_signature)]))
      let create = [
        Instruction::ref_func(FuncIdx::new(0U)),
        Instruction::cont_new(cont),
      ]
      let body = [Instruction::call(FuncIdx::new(1U)), Instruction::drop()]
      match variant {
        0 => {
          body.append(create)
          body.append([Instruction::drop(), constant])
        }
        1 => {
          body.push(constant)
          body.append(create)
          body.append([
            Instruction::cont_bind(cont, bound_cont),
            Instruction::drop(),
            constant,
          ])
        }
        2 => {
          body.push(constant)
          body.append(create)
          body.push(Instruction::resume_(cont, []))
        }
        3 => {
          body.append(create)
          body.push(Instruction::resume_throw(cont, tag, []))
        }
        4 => body.push(Instruction::suspend(tag))
        _ => {
          bodies[0] = Func::new(
            Locals::from_types([]),
            Expr::new([get0, Instruction::suspend(tag), Instruction::i32_add()]),
          )
          let reference = RefType::new(true, HeapType::new(cont))
          let resumed = [constant]
          resumed.append(create)
          resumed.append([
            Instruction::resume_(cont, [
              @lib.ResumeHandler::on_label(tag, LabelIdx::new(0U)),
            ]),
            Instruction::drop(),
            Instruction::ref_null(HeapType::new(cont)),
          ])
          body.append([
            Instruction::block(
              BlockType::val_type(ValType::ref_type(reference)),
              Expr::new(resumed),
            ),
            Instruction::drop(),
            constant,
          ])
        }
      }
      add([], [i32], [], body)
      module_ = module_.with_elem_sec(
        ElemSec::new([
          Elem::new(
            ElemMode::declarative(),
            if (seed & 8UL) == 0UL {
              ElemKind::funcs([FuncIdx::new(0U)])
            } else {
              ElemKind::typed_exprs(
                RefType::new(true, HeapType::abs(AbsHeapType::func())),
                [Expr::new([Instruction::ref_func(FuncIdx::new(0U))])],
              )
            },
          ),
        ]),
      )
    }
    11 => {
      let producer = effect(1)
      producer.push(get0)
      add([i32], [i32], [], producer)
      add([i32], [], [], effect(2))
      module_ = module_.with_tag_sec(
        TagSec::new([TagType::new(TypeIdx::new(1U))]),
      )
      add([], [i32], [], [
        Instruction::try_(
          BlockType::val_type(i32),
          Expr::new([constant, Instruction::throw_(TagIdx::new(0U))]),
          [
            @lib.LegacyCatch::tagged(
              TagIdx::new(0U),
              Expr::new([
                Instruction::call(FuncIdx::new(0U)),
                Instruction::call(FuncIdx::new(1U)),
                constant,
              ]),
            ),
            @lib.LegacyCatch::all(
              Expr::new([Instruction::i32_const(I32(literal ^ 1))]),
            ),
          ],
        ),
      ])
    }
    12 => {
      add([i32], [i32], [], [get0])
      add([], [], [], [
        constant,
        Instruction::ref_func(FuncIdx::new(0U)),
        Instruction::call_ref(TypeIdx::new(0U)),
        Instruction::drop(),
      ])
      add([], [], [], [Instruction::call(FuncIdx::new(1U))])
      module_ = module_.with_elem_sec(
        ElemSec::new([
          Elem::new(
            ElemMode::declarative(),
            ElemKind::funcs([FuncIdx::new(0U)]),
          ),
        ]),
      )
    }
    13 => {
      types.push(
        RecType::new(
          SubType::comp_type(
            CompType::func(
              [ValType::ref_type(RefType::abs(AbsHeapType::func()))],
              [i32],
            ),
          ),
        ),
      )
      module_ = module_.with_import_sec(
        ImportSec::new([
          Import::new(
            Name::from_string("binaryen-intrinsics"),
            Name::from_string("call.without.effects"),
            ExternType::func(TypeIdx::new(0U)),
          ),
        ]),
      )
      add([], [i32], [], [constant])
      add([], [], [], [
        Instruction::ref_func(FuncIdx::new(1U)),
        Instruction::call(FuncIdx::new(0U)),
        Instruction::drop(),
      ])
      add([], [], [], [Instruction::call(FuncIdx::new(2U))])
      module_ = module_.with_elem_sec(
        ElemSec::new([
          Elem::new(
            ElemMode::declarative(),
            ElemKind::funcs([FuncIdx::new(1U)]),
          ),
        ]),
      )
    }
    1 => {
      // The live countdown bounds execution; the second parameter and result
      // form an unused cycle, including arithmetic in the forwarding path.
      for callee in [1U, 0U] {
        add([i32, i32], [i32], [], [
          get0,
          Instruction::if_(
            BlockType::val_type(i32),
            [
              get0,
              Instruction::i32_const(I32(1)),
              Instruction::i32_sub(),
              Instruction::local_get(LocalIdx::new(1U)),
              constant,
              Instruction::i32_add(),
              Instruction::call(FuncIdx::new(callee)),
            ],
            Some([Instruction::local_get(LocalIdx::new(1U))]),
          ),
        ])
      }
      add([], [], [], [
        Instruction::i32_const(I32(1 + (seed % 8UL).to_int())),
        constant,
        Instruction::call(FuncIdx::new(0U)),
        Instruction::drop(),
      ])
    }
    2 if loop_effect => {
      // The unused load argument must retain its trap, while the call stored
      // by the void loop must still execute once after result promotion.
      let producer = effect(1 + ((seed >> 5) & 3UL).to_int())
      producer.append([
        get0,
        Instruction::local_get(LocalIdx::new(2U)),
        Instruction::i32_add(),
      ])
      add([i32, i32, i32, i64], [i32], [], producer)
      add([], [i32], [], [constant])
      let memarg = @lib.MemArg::new(2U, None, 0UL)
      let held = (seed & 8UL) != 0UL
      let caller : Array[Instruction] = []
      if held {
        // Keep an earlier load on the stack across the whole loop. The
        // initial memory has one page, so 65536 traps before the callee runs.
        caller.append([
          Instruction::i32_const(
            I32(if (seed & 16UL) == 0UL { 0 } else { 65536 }),
          ),
          Instruction::i32_load(memarg),
        ])
      }
      caller.append([
        Instruction::loop_(
          BlockType::void_(),
          Expr::new([
            get0,
            Instruction::local_get(LocalIdx::new(1U)),
            Instruction::i32_load(memarg),
            Instruction::local_get(LocalIdx::new(2U)),
            Instruction::i64_const(I64(seed.reinterpret_as_int64())),
            Instruction::call(FuncIdx::new(0U)),
            Instruction::local_set(LocalIdx::new(3U)),
          ]),
        ),
        Instruction::local_get(LocalIdx::new(3U)),
      ])
      if held {
        caller.push(Instruction::i32_add())
      }
      add([i32, i32, i32], [i32], [i32], caller)
      module_ = module_.with_mem_sec(
        MemSec::new([MemType::new(Limits::i32(1U, None))]),
      )
    }
    2 => {
      add([i32, i32], [i32], [], [
        get0,
        Instruction::if_(
          BlockType::val_type(i32),
          [Instruction::local_get(LocalIdx::new(1U)), Instruction::return_()],
          Some([constant]),
        ),
      ])
      add([i32], [], [], [])
      add([i32], [], [], [
        get0,
        constant,
        Instruction::call(FuncIdx::new(0U)),
        Instruction::call(FuncIdx::new(1U)),
      ])
    }
    3 => {
      module_ = module_.with_global_sec(
        GlobalSec::new([
          Global::new(
            GlobalType::new(i32, true),
            Expr::new([Instruction::i32_const(I32(0))]),
          ),
        ]),
      )
      add([i32], [i32], [], [
        get0,
        Instruction::global_set(GlobalIdx::new(0U)),
        get0,
      ])
      add([i32, i32, i32], [i32], [], [get0])
      add([], [i32], [], [
        constant,
        Instruction::call(FuncIdx::new(0U)),
        Instruction::i32_const(I32(2)),
        Instruction::call(FuncIdx::new(0U)),
        Instruction::i32_const(I32(3)),
        Instruction::call(FuncIdx::new(0U)),
        Instruction::call(FuncIdx::new(1U)),
      ])
    }
    4 => {
      let variant = (seed % 4UL).to_int()
      let producer = effect(1)
      let nested = (seed & 4UL) != 0UL
      let locals = if nested { [i32] } else { [] }
      if nested {
        let tuple_type = TypeIdx::new(types.length().reinterpret_as_uint())
        types.push(
          RecType::new(SubType::comp_type(CompType::func([], [i32, i64]))),
        )
        let mut value = [
          get0,
          Instruction::i64_const(I64(seed.reinterpret_as_int64())),
        ]
        for depth = 0; depth < 2 + (seed % 4UL).to_int(); depth = depth + 1 {
          value = [
            get0,
            Instruction::i32_const(I32(depth)),
            Instruction::i32_eq(),
            Instruction::if_(
              BlockType::type_idx(tuple_type),
              [
                Instruction::local_get(LocalIdx::new(1U)),
                Instruction::i32_const(I32(literal ^ depth)),
                Instruction::local_set(LocalIdx::new(1U)),
                Instruction::i64_const(I64(depth.to_int64())),
              ],
              Some(value),
            ),
          ]
        }
        producer.append(value)
        producer.append([
          Instruction::local_get(LocalIdx::new(1U)),
          Instruction::global_set(counter),
        ])
      } else {
        producer.append([
          get0,
          Instruction::i64_const(I64(seed.reinterpret_as_int64())),
        ])
      }
      add([i32], [i32, i64], locals, producer)
      let sink = effect(2)
      let results = match variant {
        0 => []
        1 => {
          sink.push(get0)
          [i32]
        }
        2 => {
          sink.push(Instruction::local_get(LocalIdx::new(1U)))
          [i64]
        }
        _ => {
          sink.append([get0, Instruction::local_get(LocalIdx::new(1U))])
          [i32, i64]
        }
      }
      add([i32, i64], results, [], sink)
      let caller = [
        constant,
        Instruction::call(FuncIdx::new(0U)),
        Instruction::call(FuncIdx::new(1U)),
      ]
      add([], results, [], caller)
    }
    5 => {
      add([i32], [i32], [], [get0])
      add([i32], [i32], [], [get0, Instruction::return_call(FuncIdx::new(0U))])
      add([], [], [], [
        constant,
        Instruction::call(FuncIdx::new(1U)),
        Instruction::drop(),
      ])
    }
    6 | 7 => {
      add([i32], [i32], [], [get0])
      let call = if family == 7 {
        Instruction::return_call_indirect(TypeIdx::new(0U), TableIdx::new(0U))
      } else {
        Instruction::call_indirect(TypeIdx::new(0U), TableIdx::new(0U))
      }
      add([i32], [i32], [], [get0, Instruction::i32_const(I32(0)), call])
      add([], [], [], [
        constant,
        Instruction::call(FuncIdx::new(1U)),
        Instruction::drop(),
      ])
      module_ = module_
        .with_table_sec(
          TableSec::new([
            Table::new(
              TableType::new(
                RefType::abs(AbsHeapType::func()),
                Limits::i32(1U, None),
              ),
              None,
            ),
          ]),
        )
        .with_elem_sec(
          ElemSec::new([
            Elem::new(
              ElemMode::active(
                TableIdx::new(0U),
                Expr::new([Instruction::i32_const(I32(0))]),
              ),
              ElemKind::funcs([FuncIdx::new(0U)]),
            ),
          ]),
        )
    }
    8 => {
      types.push(
        RecType::new(
          SubType::comp_type(
            CompType::struct_([
              FieldType::new(StorageType::val_type(i32), Mut::const_()),
            ]),
          ),
        ),
      )
      let ref_type = ValType::ref_type(
        RefType::new(false, HeapType::new(TypeIdx::new(0U))),
      )
      add([ref_type], [], [], [])
      add([ref_type], [], [], [get0, Instruction::call(FuncIdx::new(0U))])
      add([], [], [], [
        constant,
        Instruction::struct_new(TypeIdx::new(0U)),
        Instruction::call(FuncIdx::new(1U)),
      ])
    }
    9 => {
      add([i32], [i32], [], [
        constant,
        Instruction::local_set(LocalIdx::new(0U)),
        get0,
      ])
      add([i32], [], [i32], [
        get0,
        Instruction::local_tee(LocalIdx::new(1U)),
        Instruction::drop(),
      ])
      add([], [], [], [
        constant,
        Instruction::call(FuncIdx::new(0U)),
        Instruction::call(FuncIdx::new(1U)),
      ])
    }
    _ => {
      add([i32], [i32], [], [get0, constant, Instruction::i32_xor()])
      add([i32], [], [], [])
      add([i32], [], [], [
        get0,
        Instruction::call(FuncIdx::new(0U)),
        Instruction::call(FuncIdx::new(1U)),
      ])
    }
  }
  let exports = [
    Export::new(
      Name::from_string("run"),
      ExternIdx::func(FuncIdx::new(if family == 13 { 3U } else { 2U })),
    ),
  ]
  if family == 3 || family == 4 || family == 11 || loop_effect {
    exports.push(
      Export::new(Name::from_string("effects"), ExternIdx::global(counter)),
    )
  }
  if loop_effect {
    exports.push(
      Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
    )
  }
  module_
  .with_type_sec(TypeSec::new(types))
  .with_func_sec(FuncSec::new(type_indices))
  .with_code_sec(CodeSec::new(bodies))
  .with_export_sec(ExportSec::new(exports))
}

///|
fn gen_valid_dae2_pending_memory_module(seed : UInt64) -> Module {
  let i32 = ValType::i32()
  let address = if (seed & 2UL) == 0UL { 0 } else { 65532 }
  let addr = Instruction::i32_const(I32(address))
  let memarg = @lib.MemArg::new(2U, None, 0UL)
  let initial = (seed.to_uint() ^ 0x12345678U).reinterpret_as_int()
  Module::new()
  .with_type_sec(
    TypeSec::new([
      RecType::new(SubType::comp_type(CompType::func([], []))),
      RecType::new(SubType::comp_type(CompType::func([i32, i32], [i32]))),
      RecType::new(SubType::comp_type(CompType::func([], [i32]))),
    ]),
  )
  .with_func_sec(
    FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(2U)]),
  )
  .with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
  .with_code_sec(
    CodeSec::new([
      Func::new(
        Locals::from_types([]),
        Expr::new([
          addr,
          Instruction::i32_const(I32(initial ^ 1)),
          Instruction::i32_store(memarg),
        ]),
      ),
      Func::new(
        Locals::from_types([]),
        Expr::new([Instruction::local_get(LocalIdx::new(0U))]),
      ),
      Func::new(
        Locals::from_types([]),
        Expr::new([
          addr,
          Instruction::i32_const(I32(initial)),
          Instruction::i32_store(memarg),
          addr,
          Instruction::i32_load(memarg),
          Instruction::call(FuncIdx::new(0U)),
          Instruction::i32_const(I32(7)),
          Instruction::call(FuncIdx::new(1U)),
        ]),
      ),
    ]),
  )
  .with_export_sec(
    ExportSec::new([
      Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
      Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
    ]),
  )
}

///|
fn gen_valid_dae2_local_state_module(seed : UInt64, capture : Bool) -> Module {
  let i32 = ValType::i32()
  let get = fn(index : UInt32) { Instruction::local_get(LocalIdx::new(index)) }
  let number = fn(value : Int32) { Instruction::i32_const(I32(value)) }
  let initial = (seed.to_uint() ^ 0x1234U).reinterpret_as_int()
  let ma = MemArg::new(2U, None, 0UL)
  let body = if capture {
    [
      Instruction::memory_size(MemIdx::new(0U)),
      Instruction::local_tee(LocalIdx::new(1U)),
      number(0),
      Instruction::i32_load(ma),
      get(1U),
      Instruction::i32_add(),
      Instruction::i32_add(),
    ]
  } else {
    [
      get(0U),
      Instruction::if_(
        BlockType::val_type(i32),
        [number(initial), Instruction::local_set(LocalIdx::new(1U)), number(0)],
        Some([
          number(initial ^ 1),
          Instruction::local_set(LocalIdx::new(1U)),
          number(1),
        ]),
      ),
      Instruction::local_set(LocalIdx::new(2U)),
      get(1U),
    ]
  }
  let module_ = Module::new()
    .with_type_sec(
      TypeSec::new([
        RecType::new(SubType::comp_type(CompType::func([i32], [i32]))),
        RecType::new(SubType::comp_type(CompType::func([i32, i32], [i32]))),
      ]),
    )
    .with_func_sec(
      FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(0U)]),
    )
    .with_code_sec(
      CodeSec::new([
        Func::new(Locals::from_types([i32, i32]), Expr::new(body)),
        Func::new(Locals::from_types([]), Expr::new([get(0U)])),
        Func::new(
          Locals::from_types([]),
          Expr::new([
            get(0U),
            Instruction::call(FuncIdx::new(0U)),
            number(7),
            Instruction::call(FuncIdx::new(1U)),
          ]),
        ),
      ]),
    )
    .with_export_sec(
      ExportSec::new([
        Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
      ]),
    )
  if capture {
    module_.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
  } else {
    module_
  }
}

///|
fn gen_valid_dae2_overlap_module(seed : UInt64, named : Bool) -> Module {
  let i32 = ValType::i32()
  let literal = (seed ^ (seed >> 32)).to_int()
  let get = fn(index : UInt32) { Instruction::local_get(LocalIdx::new(index)) }
  let set = fn(index : UInt32) { Instruction::local_set(LocalIdx::new(index)) }
  let constant = fn(value : Int32) { Instruction::i32_const(I32(value)) }
  let producer = [
    Instruction::global_get(GlobalIdx::new(0U)),
    constant(1),
    Instruction::i32_add(),
    Instruction::global_set(GlobalIdx::new(0U)),
    constant(literal),
    constant(literal ^ 101),
    constant(literal ^ 202),
  ]
  let consumer = [
    get(0U),
    get(1U),
    constant(31),
    Instruction::i32_mul(),
    Instruction::i32_add(),
    get(2U),
    constant(997),
    Instruction::i32_mul(),
    Instruction::i32_add(),
  ]
  let runner = [
    constant(literal),
    Instruction::call(FuncIdx::new(0U)),
    set(6U),
    set(5U),
    Instruction::local_tee(LocalIdx::new(4U)),
    set(8U),
    get(5U),
    set(7U),
    Instruction::block(
      BlockType::type_idx(TypeIdx::new(3U)),
      Expr::new([get(8U), get(7U), get(6U)]),
    ),
  ]
  if (seed & 1UL) == 0UL {
    runner.append([set(6U), set(10U)])
  } else {
    runner.append([set(10U), set(6U)])
  }
  runner.append([
    set(9U),
    get(9U),
    get(10U),
    get(6U),
    Instruction::call(FuncIdx::new(1U)),
  ])
  let module_ = Module::new()
    .with_type_sec(
      TypeSec::new([
        RecType::new(SubType::comp_type(CompType::func([i32], [i32, i32, i32]))),
        RecType::new(SubType::comp_type(CompType::func([i32, i32, i32], [i32]))),
        RecType::new(SubType::comp_type(CompType::func([], [i32]))),
        RecType::new(SubType::comp_type(CompType::func([], [i32, i32, i32]))),
      ]),
    )
    .with_func_sec(
      FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(2U)]),
    )
    .with_code_sec(
      CodeSec::new([
        Func::new(Locals::empty(), Expr::new(producer)),
        Func::new(Locals::empty(), Expr::new(consumer)),
        Func::new(Locals::from_types(Array::make(11, i32)), Expr::new(runner)),
      ]),
    )
    .with_global_sec(
      GlobalSec::new([
        Global::new(GlobalType::new(i32, true), Expr::new([constant(0)])),
      ]),
    )
    .with_export_sec(
      ExportSec::new([
        Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
        Export::new(
          Name::from_string("effects"),
          ExternIdx::global(GlobalIdx::new(0U)),
        ),
      ]),
    )
  if named {
    module_.with_name_sec(
      NameSec::new(
        label_names=Some(
          IndirectNameMap::new([
            IndirectNameAssoc::new(
              2U,
              NameMap::new([
                NameAssoc::new(0U, Name::from_string("forwarded-tuple")),
              ]),
            ),
          ]),
        ),
      ),
    )
  } else {
    module_
  }
}

///|
fn gen_valid_dae2_inserted_control_module(seed : UInt64) -> Module {
  let i32 = ValType::i32()
  let get = fn(index : UInt32) { Instruction::local_get(LocalIdx::new(index)) }
  let number = fn(value : Int32) { Instruction::i32_const(I32(value)) }
  let state = GlobalIdx::new(0U)
  let observed = GlobalIdx::new(1U)
  let signature = TypeIdx::new(0U)
  let literal = (seed ^ (seed >> 32)).to_int() | 1
  // Read the exposed state inside the observer, so moving it across a global
  // write is observable as well as moving the later parameter tee before it.
  let observer = [
    Instruction::global_get(observed),
    number(31),
    Instruction::i32_mul(),
    get(0U),
    number(997),
    Instruction::i32_mul(),
    Instruction::i32_add(),
    get(1U),
    Instruction::i32_add(),
    Instruction::global_get(state),
    number(3571),
    Instruction::i32_mul(),
    Instruction::i32_add(),
    Instruction::global_set(observed),
    number(literal),
  ]
  let runner = [
    get(1U),
    Instruction::if_(
      BlockType::void_(),
      [
        get(0U),
        get(1U),
        Instruction::call(FuncIdx::new(0U)),
        Instruction::drop(),
        get(1U),
        Instruction::local_set(LocalIdx::new(2U)),
      ],
      None,
    ),
  ]
  if seed % 12UL == 0UL {
    runner.append([
      number(3),
      number(4),
      Instruction::call(FuncIdx::new(0U)),
      Instruction::drop(),
    ])
  } else {
    runner.append([number(0), Instruction::global_set(state)])
  }
  runner.append([
    get(2U),
    Instruction::if_(
      BlockType::void_(),
      [get(2U), Instruction::global_set(state)],
      None,
    ),
    number(literal),
    Instruction::local_tee(LocalIdx::new(0U)),
    get(0U),
    Instruction::i32_add(),
  ])
  Module::new()
  .with_type_sec(
    TypeSec::new([
      RecType::new(SubType::comp_type(CompType::func([i32, i32], [i32]))),
    ]),
  )
  .with_func_sec(FuncSec::new([signature, signature, signature]))
  .with_global_sec(
    GlobalSec::new([
      Global::new(GlobalType::new(i32, true), Expr::new([number(literal)])),
      Global::new(GlobalType::new(i32, true), Expr::new([number(0)])),
    ]),
  )
  .with_code_sec(
    CodeSec::new([
      Func::new(Locals::empty(), Expr::new(observer)),
      Func::new(Locals::from_types([i32]), Expr::new(runner)),
      Func::new(
        Locals::empty(),
        Expr::new([get(0U), get(1U), Instruction::call(FuncIdx::new(1U))]),
      ),
    ]),
  )
  .with_export_sec(
    ExportSec::new([
      Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
      Export::new(Name::from_string("state"), ExternIdx::global(state)),
      Export::new(Name::from_string("observed"), ExternIdx::global(observed)),
    ]),
  )
}

///|
fn gen_valid_dae2_derived_pointer_module(seed : UInt64) -> Module {
  let i32 = ValType::i32()
  let get = fn(index : UInt32) { Instruction::local_get(LocalIdx::new(index)) }
  let set = fn(index : UInt32) { Instruction::local_set(LocalIdx::new(index)) }
  let number = fn(value : Int32) { Instruction::i32_const(I32(value)) }
  let base = ((seed >> 32) % 256UL).to_int() + 32
  Module::new()
  .with_type_sec(
    TypeSec::new([
      RecType::new(SubType::comp_type(CompType::func([i32, i32], [i32]))),
      RecType::new(SubType::comp_type(CompType::func([i32], [i32]))),
    ]),
  )
  .with_func_sec(
    FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(1U)]),
  )
  .with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
  .with_code_sec(
    CodeSec::new([
      // The second allocation argument is unused; DAE2 can remove it. Mask the
      // returned address so every generated invocation has an in-bounds header.
      Func::new(
        Locals::empty(),
        Expr::new([
          get(0U),
          number(255),
          Instruction::i32_and(),
          number(base),
          Instruction::i32_add(),
        ]),
      ),
      Func::new(
        Locals::from_types([i32, i32]),
        Expr::new([
          number(8),
          get(0U),
          Instruction::i32_add(),
          number(seed.to_int()),
          Instruction::call(FuncIdx::new(0U)),
          set(1U),
          get(1U),
          number(8),
          Instruction::i32_add(),
          set(2U),
          get(1U),
          number(4),
          Instruction::i32_store(MemArg::new(0U, None, 0UL)),
          get(2U),
        ]),
      ),
      Func::new(
        Locals::empty(),
        Expr::new([get(0U), Instruction::call(FuncIdx::new(1U))]),
      ),
    ]),
  )
  .with_export_sec(
    ExportSec::new([
      Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
      Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
    ]),
  )
}