///|
fn gen_valid_vacuum_unread_tee_config() -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 3,
max_imports: 1,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 1,
max_globals: 1,
max_tags: 1,
max_elems: 0,
max_datas: 0,
max_params: 1,
max_results: 2,
max_locals: 1,
max_body_statements: 30,
max_body_depth: 4,
max_module_byte_size_budget: Some(200009),
features: GenValidFeatureToggles::{
..base.features,
allow_imports: true,
allow_tables: false,
allow_mems: true,
allow_globals: true,
allow_tags: true,
allow_elems: false,
allow_datas: false,
allow_ref_types: true,
allow_calls: true,
allow_call_indirect: false,
allow_tail_calls: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_memory64: false,
allow_atomics: false,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
},
}
}
///|
// Dedicated inputs contain real tees, exported observations and effectful host
// calls. Seed-selected negatives exercise complete-read proof and opaque EH.
fn gen_valid_vacuum_unread_tee_module(seed : UInt64) -> Module {
let family = (seed % 13UL).to_int()
let value = @lib.I32(((seed >> 4) & 0x7fffUL).to_int() + 17)
let i32 = ValType::i32()
let tee_local = LocalIdx::new(1U)
let seen = GlobalIdx::new(0U)
let produce = FuncIdx::new(0U)
let tag = TagIdx::new(0U)
let types = [
RecType::new(SubType::comp_type(CompType::func([i32], [i32]))),
RecType::new(SubType::comp_type(CompType::func([i32], [i32]))),
]
let mut locals = Locals::single(1U, i32)
let mut has_tag = false
let mut has_memory = false
let body = match family {
0 =>
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_add(),
]
1 => {
types[0] = RecType::new(
SubType::comp_type(CompType::func([i32], [ValType::i64(), i32])),
)
types[1] = types[0]
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
]
}
2 => {
let ref_ = ValType::externref()
types[0] = RecType::new(
SubType::comp_type(CompType::func([ref_], [ref_])),
)
types[1] = types[0]
locals = Locals::single(1U, ref_)
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
]
}
3 | 4 => {
let struct_ = TypeIdx::new(2U)
types.push(
RecType::new(
SubType::comp_type(
CompType::struct_([
FieldType::new(StorageType::val_type(i32), Mut::var_()),
]),
),
),
)
let ref_ = ValType::ref_type(
RefType::new(
family == 4 || (seed & 16UL) != 0UL,
HeapType::new(struct_),
),
)
locals = Locals::single(1U, ref_)
if family == 3 {
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::struct_new(struct_),
Instruction::local_tee(tee_local),
Instruction::struct_get(struct_, U32(0U)),
]
} else {
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::drop(),
Instruction::ref_null(HeapType::new(struct_)),
Instruction::local_tee(tee_local),
Instruction::ref_is_null(),
]
}
}
5 =>
[
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::global_set(seen),
Instruction::br(LabelIdx::new(1U)),
]),
),
]),
),
Instruction::global_get(seen),
]
6 =>
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::global_set(seen),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::global_get(seen), Instruction::global_set(seen)],
Some([
Instruction::local_get(tee_local),
Instruction::global_set(seen),
]),
),
Instruction::global_get(seen),
]
7 => {
has_tag = true
[
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::global_set(seen),
Instruction::throw_(tag),
]),
),
]),
),
Instruction::global_get(seen),
]
}
8 =>
[
Instruction::try_(
BlockType::val_type(i32),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
]),
[@lib.LegacyCatch::all(Expr::new([Instruction::i32_const(value)]))],
),
]
9 => {
has_tag = true
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::drop(),
Instruction::try_(
BlockType::void_(),
Expr::new([Instruction::throw_(tag)]),
[
@lib.LegacyCatch::all(
Expr::new([
Instruction::local_get(tee_local),
Instruction::global_set(seen),
]),
),
],
),
Instruction::global_get(seen),
]
}
10 =>
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::global_set(seen),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(@lib.I32(0)),
Instruction::i32_div_s(),
]
11 =>
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::global_set(seen),
],
Some([
Instruction::i32_const(value),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::global_set(seen),
]),
),
Instruction::global_get(seen),
]
_ => {
has_memory = true
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(produce),
Instruction::local_tee(tee_local),
Instruction::global_set(seen),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_load(gen_valid_memarg()),
]
}
}
if has_tag {
types.push(RecType::new(SubType::comp_type(CompType::func([], []))))
}
let mod_ = Module::new()
.with_type_sec(TypeSec::new(types))
.with_import_sec(
ImportSec::new([
Import::new(
Name::from_string("env"),
Name::from_string("produce"),
ExternType::func(TypeIdx::new(0U)),
),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(i32, true),
Expr::new([Instruction::i32_const(value)]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
Export::new(Name::from_string("seen"), ExternIdx::global(seen)),
]),
)
.with_code_sec(CodeSec::new([Func::new(locals, Expr::new(body))]))
let mod_ = if has_tag {
mod_.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(2U))]))
} else {
mod_
}
if has_memory {
mod_.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
} else {
mod_
}
}