///|
fn gen_valid_global_refining_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let tag = match profile {
GlobalRefiningPrivateWritesProfile => 180
GlobalRefiningExportBoundariesProfile => 181
GlobalRefiningImportAliasesProfile => 182
GlobalRefiningSubtypeJoinsProfile => 183
_ => 180
}
GenValidConfig::{
..base,
max_type_defs: 8,
max_imports: 2,
max_defined_funcs: 1,
max_globals: 3,
max_params: 1,
max_results: 1,
max_locals: 0,
max_body_statements: tag,
max_body_depth: 4,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: profile == GlobalRefiningImportAliasesProfile,
allow_globals: true,
allow_ref_types: true,
allow_subtyping_topology: true,
allow_const_expr_variants: true,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: false,
allow_heap_store_optimization_body_generator: false,
allow_heap2local_body_generator: false,
},
}
}
///|
fn gen_valid_is_global_refining_profile_config(config : GenValidConfig) -> Bool {
[
GlobalRefiningPrivateWritesProfile,
GlobalRefiningExportBoundariesProfile,
GlobalRefiningImportAliasesProfile,
GlobalRefiningSubtypeJoinsProfile,
].any(fn(profile) {
config == gen_valid_global_refining_profile_config(profile)
})
}
///|
fn gen_valid_gr_construct(
type_idx : TypeIdx,
value : Int32,
extra_field : Bool,
) -> Array[Instruction] {
let body = [Instruction::i32_const(I32(value))]
if extra_field {
body.push(Instruction::i32_const(I32(value + 1)))
}
body.push(Instruction::struct_new(type_idx))
body
}
///|
fn gen_valid_global_refining_profile_module(ctx : GenValidContext) -> Module {
let config = ctx.config
let seed = ctx.root_seed
let value = (seed & 0x7ffffUL).to_int()
let fields = [
FieldType::new(StorageType::val_type(ValType::i32()), Mut::const_()),
]
let types = [
RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [ValType::i32()])),
),
]
let depth = 1 + (seed % 3UL).to_int()
for level = 0; level < depth; level = level + 1 {
types.push(
RecType::new(
SubType::new(
false,
if level == 0 {
[]
} else {
[TypeIdx::new(level.to_uint())]
},
CompType::struct_(fields),
),
),
)
}
let parent = TypeIdx::new(depth.to_uint())
let left = TypeIdx::new((depth + 1).to_uint())
let right = TypeIdx::new((depth + 2).to_uint())
types.push(
RecType::new(SubType::new(true, [parent], CompType::struct_(fields))),
)
types.push(
RecType::new(
SubType::new(true, [parent], CompType::struct_([fields[0], fields[0]])),
),
)
let anyref = ValType::ref_type(RefType::abs(AbsHeapType::any()))
let externref = ValType::ref_type(RefType::abs(AbsHeapType::extern_()))
let imports : Array[Import] = []
let globals : Array[Global] = []
let exports = [
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]
let body : Array[Instruction] = []
let mut target = 0U
let mut read_target = 0U
if config ==
gen_valid_global_refining_profile_config(GlobalRefiningImportAliasesProfile) {
imports.push(
Import::new(
Name::from_string("host"),
Name::from_string("immutable"),
ExternType::global(GlobalType::new(externref, false)),
),
)
imports.push(
Import::new(
Name::from_string("host"),
Name::from_string("mutable"),
ExternType::global(GlobalType::new(externref, true)),
),
)
globals.push(
Global::new(
GlobalType::new(externref, false),
Expr::new([Instruction::global_get(GlobalIdx::new(0U))]),
),
)
globals.push(
Global::new(
GlobalType::new(externref, false),
Expr::new([Instruction::global_get(GlobalIdx::new(2U))]),
),
)
target = 4U
read_target = target
exports.push(
Export::new(
Name::from_string("immutable_alias"),
ExternIdx::global(GlobalIdx::new(3U)),
),
)
exports.push(
Export::new(
Name::from_string("imported_mutable"),
ExternIdx::global(GlobalIdx::new(1U)),
),
)
body.append([
Instruction::global_get(GlobalIdx::new(1U)),
Instruction::drop(),
Instruction::global_get(GlobalIdx::new(3U)),
Instruction::drop(),
])
}
let nullable = config ==
gen_valid_global_refining_profile_config(GlobalRefiningPrivateWritesProfile) &&
(seed & 1UL) != 0UL
globals.push(
Global::new(
GlobalType::new(anyref, true),
Expr::new(
if nullable {
[Instruction::ref_null(HeapType::abs(AbsHeapType::any()))]
} else {
gen_valid_gr_construct(left, value, false)
},
),
),
)
if config ==
gen_valid_global_refining_profile_config(
GlobalRefiningExportBoundariesProfile,
) {
globals.push(
Global::new(
GlobalType::new(anyref, false),
Expr::new(gen_valid_gr_construct(left, value, false)),
),
)
read_target = 1U
exports.push(
Export::new(
Name::from_string("mutable_boundary"),
ExternIdx::global(GlobalIdx::new(0U)),
),
)
exports.push(
Export::new(
Name::from_string("immutable_boundary"),
ExternIdx::global(GlobalIdx::new(1U)),
),
)
}
if config ==
gen_valid_global_refining_profile_config(GlobalRefiningSubtypeJoinsProfile) {
let yes = gen_valid_gr_construct(left, value + 1, false)
yes.push(Instruction::global_set(GlobalIdx::new(target)))
let no = gen_valid_gr_construct(right, value + 2, true)
no.push(Instruction::global_set(GlobalIdx::new(target)))
body.append([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), yes, Some(no)),
])
} else {
body.append(gen_valid_gr_construct(left, value + 1, false))
body.push(Instruction::global_set(GlobalIdx::new(target)))
}
body.append([
Instruction::global_get(GlobalIdx::new(read_target)),
Instruction::ref_cast(false, HeapType::new(parent)),
Instruction::struct_get(parent, U32::new(0U)),
])
let mod_ = Module::new()
.with_type_sec(TypeSec::new(types))
.with_global_sec(GlobalSec::new(globals))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]))
.with_export_sec(ExportSec::new(exports))
if imports.is_empty() {
mod_
} else {
mod_.with_import_sec(ImportSec::new(imports))
}
}