///|
pub enum GenValidMode {
Natural
CoverageForced
} derive(Eq, Debug)
///|
pub impl Show for GenValidMode with fn output(self, logger) {
match self {
Natural => logger.write_string("Natural")
CoverageForced => logger.write_string("CoverageForced")
}
}
///|
pub struct GenValidSectionBias {
imports_percent : Int32
tables_percent : Int32
mems_percent : Int32
globals_percent : Int32
tags_percent : Int32
start_percent : Int32
elems_percent : Int32
datas_percent : Int32
} derive(Eq, Debug)
///|
pub impl Show for GenValidSectionBias with fn output(self, logger) {
logger.write_string("GenValidSectionBias {imports_percent: ")
self.imports_percent.output(logger)
logger.write_string(", tables_percent: ")
self.tables_percent.output(logger)
logger.write_string(", mems_percent: ")
self.mems_percent.output(logger)
logger.write_string(", globals_percent: ")
self.globals_percent.output(logger)
logger.write_string(", tags_percent: ")
self.tags_percent.output(logger)
logger.write_string(", start_percent: ")
self.start_percent.output(logger)
logger.write_string(", elems_percent: ")
self.elems_percent.output(logger)
logger.write_string(", datas_percent: ")
self.datas_percent.output(logger)
logger.write_char('}')
}
///|
pub fn GenValidSectionBias::natural_default() -> GenValidSectionBias {
{
imports_percent: 30,
tables_percent: 30,
mems_percent: 30,
globals_percent: 67,
tags_percent: 20,
start_percent: 10,
elems_percent: 20,
datas_percent: 20,
}
}
///|
pub fn GenValidSectionBias::coverage_forced_default() -> GenValidSectionBias {
{
imports_percent: 100,
tables_percent: 100,
mems_percent: 100,
globals_percent: 100,
tags_percent: 100,
start_percent: 100,
elems_percent: 100,
datas_percent: 100,
}
}
///|
pub struct GenValidFeatureToggles {
allow_imports : Bool
allow_tables : Bool
allow_mems : Bool
allow_globals : Bool
allow_tags : Bool
allow_start : Bool
allow_elems : Bool
allow_datas : Bool
allow_ref_types : Bool
allow_v128 : Bool
allow_relaxed_simd : Bool
allow_calls : Bool
allow_call_indirect : Bool
allow_tail_calls : Bool
allow_branch_heavy_control : Bool
allow_memory_limit_variants : Bool
allow_table_limit_variants : Bool
allow_const_expr_variants : Bool
allow_shared_memories : Bool
allow_memory64 : Bool
allow_atomics : Bool
allow_subtyping_topology : Bool
allow_name_custom_sections : Bool
allow_typed_body_generator : Bool
allow_ssa_nomerge_body_generator : Bool
allow_heap_store_optimization_body_generator : Bool
allow_heap2local_body_generator : Bool
} derive(Eq, Debug)
///|
pub impl Show for GenValidFeatureToggles with fn output(self, logger) {
logger.write_string(", allow_imports:")
self.allow_imports.output(logger)
logger.write_string(", allow_tables:")
self.allow_tables.output(logger)
logger.write_string(", allow_mems:")
self.allow_mems.output(logger)
logger.write_string(", allow_globals:")
self.allow_globals.output(logger)
logger.write_string(", allow_tags:")
self.allow_tags.output(logger)
logger.write_string(", allow_start:")
self.allow_start.output(logger)
logger.write_string(", allow_elems:")
self.allow_elems.output(logger)
logger.write_string(", allow_datas:")
self.allow_datas.output(logger)
logger.write_string(", allow_ref_types:")
self.allow_ref_types.output(logger)
logger.write_string(", allow_v128:")
self.allow_v128.output(logger)
logger.write_string(", allow_relaxed_simd:")
self.allow_relaxed_simd.output(logger)
logger.write_string(", allow_calls:")
self.allow_calls.output(logger)
logger.write_string(", allow_call_indirect:")
self.allow_call_indirect.output(logger)
logger.write_string(", allow_tail_calls:")
self.allow_tail_calls.output(logger)
logger.write_string(", allow_branch_heavy_control:")
self.allow_branch_heavy_control.output(logger)
logger.write_string(", allow_memory_limit_variants:")
self.allow_memory_limit_variants.output(logger)
logger.write_string(", allow_table_limit_variants:")
self.allow_table_limit_variants.output(logger)
logger.write_string(", allow_const_expr_variants:")
self.allow_const_expr_variants.output(logger)
logger.write_string(", allow_shared_memories:")
self.allow_shared_memories.output(logger)
logger.write_string(", allow_memory64:")
self.allow_memory64.output(logger)
logger.write_string(", allow_atomics:")
self.allow_atomics.output(logger)
logger.write_string(", allow_subtyping_topology:")
self.allow_subtyping_topology.output(logger)
logger.write_string(", allow_name_custom_sections:")
self.allow_name_custom_sections.output(logger)
logger.write_string(", allow_typed_body_generator:")
self.allow_typed_body_generator.output(logger)
logger.write_string(", allow_ssa_nomerge_body_generator:")
self.allow_ssa_nomerge_body_generator.output(logger)
logger.write_string(", allow_heap_store_optimization_body_generator:")
self.allow_heap_store_optimization_body_generator.output(logger)
logger.write_string(", allow_heap2local_body_generator:")
self.allow_heap2local_body_generator.output(logger)
}
///|
pub fn GenValidFeatureToggles::natural_default() -> GenValidFeatureToggles {
{
allow_imports: true,
allow_tables: true,
allow_mems: true,
allow_globals: true,
allow_tags: true,
allow_start: true,
allow_elems: true,
allow_datas: true,
allow_ref_types: true,
allow_v128: true,
allow_relaxed_simd: false,
allow_calls: true,
allow_call_indirect: true,
allow_tail_calls: true,
allow_branch_heavy_control: true,
allow_memory_limit_variants: true,
allow_table_limit_variants: true,
allow_const_expr_variants: true,
allow_shared_memories: true,
allow_memory64: true,
allow_atomics: true,
allow_subtyping_topology: true,
allow_name_custom_sections: true,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: false,
allow_heap_store_optimization_body_generator: false,
allow_heap2local_body_generator: false,
}
}
///|
pub fn GenValidFeatureToggles::coverage_forced_default() -> GenValidFeatureToggles {
GenValidFeatureToggles::{
..GenValidFeatureToggles::natural_default(),
allow_calls: true,
allow_call_indirect: true,
allow_tail_calls: true,
allow_branch_heavy_control: true,
allow_memory_limit_variants: true,
allow_table_limit_variants: true,
allow_const_expr_variants: true,
allow_shared_memories: true,
allow_memory64: true,
allow_atomics: true,
allow_subtyping_topology: true,
allow_name_custom_sections: true,
}
}
///|
pub enum GenValidProposalFeature {
GcFeature
FunctionReferencesFeature
TailCallsFeature
ExceptionsFeature
SimdFeature
RelaxedSimdFeature
AtomicsFeature
BulkMemoryFeature
MultiMemoryFeature
Memory64Feature
ExtendedConstFeature
ReferenceTypesFeature
} derive(Eq, Debug)
///|
pub struct GenValidProposalFeatureGateRow {
feature : GenValidProposalFeature
enabled_toggles : GenValidFeatureToggles
disabled_toggles : Array[GenValidFeatureToggles]
} derive(Eq, Debug)
///|
pub fn gen_valid_proposal_features() -> Array[GenValidProposalFeature] {
[
GcFeature,
FunctionReferencesFeature,
TailCallsFeature,
ExceptionsFeature,
SimdFeature,
RelaxedSimdFeature,
AtomicsFeature,
BulkMemoryFeature,
MultiMemoryFeature,
Memory64Feature,
ExtendedConstFeature,
ReferenceTypesFeature,
]
}
///|
pub fn gen_valid_proposal_feature_label(
feature : GenValidProposalFeature,
) -> String {
match feature {
GcFeature => "gc"
FunctionReferencesFeature => "function-references"
TailCallsFeature => "tail-calls"
ExceptionsFeature => "exceptions"
SimdFeature => "simd"
RelaxedSimdFeature => "relaxed-simd"
AtomicsFeature => "atomics"
BulkMemoryFeature => "bulk-memory"
MultiMemoryFeature => "multi-memory"
Memory64Feature => "memory64"
ExtendedConstFeature => "extended-const"
ReferenceTypesFeature => "reference-types"
}
}
///|
pub fn gen_valid_proposal_feature_enabled(
toggles : GenValidFeatureToggles,
feature : GenValidProposalFeature,
) -> Bool {
match feature {
GcFeature => toggles.allow_ref_types && toggles.allow_subtyping_topology
FunctionReferencesFeature =>
toggles.allow_ref_types && toggles.allow_call_indirect
TailCallsFeature => toggles.allow_tail_calls
ExceptionsFeature => toggles.allow_tags
SimdFeature => toggles.allow_v128
RelaxedSimdFeature => toggles.allow_v128 && toggles.allow_relaxed_simd
AtomicsFeature =>
toggles.allow_mems &&
toggles.allow_shared_memories &&
toggles.allow_atomics
BulkMemoryFeature =>
toggles.allow_mems &&
(toggles.allow_datas || toggles.allow_tables || toggles.allow_elems)
MultiMemoryFeature =>
toggles.allow_mems && toggles.allow_memory_limit_variants
Memory64Feature => toggles.allow_mems && toggles.allow_memory64
ExtendedConstFeature => toggles.allow_const_expr_variants
ReferenceTypesFeature => toggles.allow_ref_types
}
}
///|
pub fn gen_valid_proposal_feature_gate_matrix() -> Array[
GenValidProposalFeatureGateRow,
] {
let all = GenValidFeatureToggles::{
..GenValidFeatureToggles::coverage_forced_default(),
allow_relaxed_simd: true,
}
[
{
feature: GcFeature,
enabled_toggles: all,
disabled_toggles: [
{ ..all, allow_ref_types: false, },
{ ..all, allow_subtyping_topology: false, },
],
},
{
feature: FunctionReferencesFeature,
enabled_toggles: all,
disabled_toggles: [
{ ..all, allow_ref_types: false, },
{ ..all, allow_call_indirect: false, },
],
},
{
feature: TailCallsFeature,
enabled_toggles: all,
disabled_toggles: [{ ..all, allow_tail_calls: false, }],
},
{
feature: ExceptionsFeature,
enabled_toggles: all,
disabled_toggles: [{ ..all, allow_tags: false, }],
},
{
feature: SimdFeature,
enabled_toggles: all,
disabled_toggles: [{ ..all, allow_v128: false, }],
},
{
feature: RelaxedSimdFeature,
enabled_toggles: all,
disabled_toggles: [
{ ..all, allow_v128: false, },
{ ..all, allow_relaxed_simd: false, },
],
},
{
feature: AtomicsFeature,
enabled_toggles: all,
disabled_toggles: [
{ ..all, allow_mems: false, },
{ ..all, allow_shared_memories: false, },
{ ..all, allow_atomics: false, },
],
},
{
feature: BulkMemoryFeature,
enabled_toggles: all,
disabled_toggles: [
{ ..all, allow_mems: false, },
{ ..all, allow_datas: false, allow_tables: false, allow_elems: false, },
],
},
{
feature: MultiMemoryFeature,
enabled_toggles: all,
disabled_toggles: [
{ ..all, allow_mems: false, },
{ ..all, allow_memory_limit_variants: false, },
],
},
{
feature: Memory64Feature,
enabled_toggles: all,
disabled_toggles: [
{ ..all, allow_mems: false, },
{ ..all, allow_memory64: false, },
],
},
{
feature: ExtendedConstFeature,
enabled_toggles: all,
disabled_toggles: [{ ..all, allow_const_expr_variants: false, }],
},
{
feature: ReferenceTypesFeature,
enabled_toggles: all,
disabled_toggles: [{ ..all, allow_ref_types: false, }],
},
]
}
///|
pub struct GenValidConfig {
mode : GenValidMode
max_type_defs : Int32
max_imports : Int32
max_defined_funcs : Int32
max_tables : Int32
max_mems : Int32
max_globals : Int32
max_tags : Int32
max_elems : Int32
max_datas : Int32
max_params : Int32
max_results : Int32
max_locals : Int32
max_body_statements : Int32
max_body_depth : Int32
max_instruction_count_budget : Int32?
max_expression_depth_budget : Int32?
max_module_byte_size_budget : Int32?
max_rec_group_size_budget : Int32?
max_section_count_budget : Int32?
max_name_length : Int32
max_segment_payload_size : Int32
section_bias : GenValidSectionBias
features : GenValidFeatureToggles
} derive(Eq, Debug)
///|
pub impl Show for GenValidConfig with fn output(self, logger) {
logger.write_string("GenValidConfig {mode: ")
self.mode.output(logger)
logger.write_string(", max_type_defs: ")
self.max_type_defs.output(logger)
logger.write_string(", max_imports: ")
self.max_imports.output(logger)
logger.write_string(", max_defined_funcs: ")
self.max_defined_funcs.output(logger)
logger.write_string(", max_tables: ")
self.max_tables.output(logger)
logger.write_string(", max_mems: ")
self.max_mems.output(logger)
logger.write_string(", max_globals: ")
self.max_globals.output(logger)
logger.write_string(", max_tags: ")
self.max_tags.output(logger)
logger.write_string(", max_elems: ")
self.max_elems.output(logger)
logger.write_string(", max_datas: ")
self.max_datas.output(logger)
logger.write_string(", max_params: ")
self.max_params.output(logger)
logger.write_string(", max_results: ")
self.max_results.output(logger)
logger.write_string(", max_locals: ")
self.max_locals.output(logger)
logger.write_string(", max_body_statements: ")
self.max_body_statements.output(logger)
logger.write_string(", max_body_depth: ")
self.max_body_depth.output(logger)
logger.write_string(", max_instruction_count_budget: ")
match self.max_instruction_count_budget {
Some(limit) => {
logger.write_string("Some(")
limit.output(logger)
logger.write_char(')')
}
None => logger.write_string("None")
}
logger.write_string(", max_expression_depth_budget: ")
match self.max_expression_depth_budget {
Some(limit) => {
logger.write_string("Some(")
limit.output(logger)
logger.write_char(')')
}
None => logger.write_string("None")
}
logger.write_string(", max_module_byte_size_budget: ")
match self.max_module_byte_size_budget {
Some(limit) => {
logger.write_string("Some(")
limit.output(logger)
logger.write_char(')')
}
None => logger.write_string("None")
}
logger.write_string(", max_rec_group_size_budget: ")
match self.max_rec_group_size_budget {
Some(limit) => {
logger.write_string("Some(")
limit.output(logger)
logger.write_char(')')
}
None => logger.write_string("None")
}
logger.write_string(", max_section_count_budget: ")
match self.max_section_count_budget {
Some(limit) => {
logger.write_string("Some(")
limit.output(logger)
logger.write_char(')')
}
None => logger.write_string("None")
}
logger.write_string(", max_name_length: ")
self.max_name_length.output(logger)
logger.write_string(", max_segment_payload_size: ")
self.max_segment_payload_size.output(logger)
logger.write_string(", section_bias: ")
self.section_bias.output(logger)
logger.write_string(", features: ")
self.features.output(logger)
logger.write_char('}')
}
///|
pub fn GenValidConfig::natural_default() -> GenValidConfig {
{
mode: Natural,
max_type_defs: 8,
max_imports: 5,
max_defined_funcs: 4,
max_tables: 3,
max_mems: 2,
max_globals: 4,
max_tags: 2,
max_elems: 3,
max_datas: 3,
max_params: 2,
max_results: 1,
max_locals: 5,
max_body_statements: 6,
max_body_depth: 2,
max_instruction_count_budget: None,
max_expression_depth_budget: None,
max_module_byte_size_budget: None,
max_rec_group_size_budget: None,
max_section_count_budget: None,
max_name_length: 64,
max_segment_payload_size: 64,
section_bias: GenValidSectionBias::natural_default(),
features: GenValidFeatureToggles::natural_default(),
}
}
///|
pub fn GenValidConfig::coverage_forced_default() -> GenValidConfig {
GenValidConfig::{
..GenValidConfig::natural_default(),
mode: CoverageForced,
max_type_defs: 18,
max_imports: 6,
max_tables: 4,
max_mems: 2,
max_globals: 5,
max_tags: 2,
max_elems: 4,
max_datas: 4,
max_locals: 6,
section_bias: GenValidSectionBias::coverage_forced_default(),
features: GenValidFeatureToggles::coverage_forced_default(),
}
}
///|
pub fn GenValidConfig::portable_coverage_forced_default() -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
GenValidConfig::{
..base,
max_tags: 0,
features: GenValidFeatureToggles::{
..base.features,
allow_ref_types: false,
allow_tags: false,
},
}
}
///|
pub fn GenValidConfig::binaryen_oracle_coverage_forced_default() -> GenValidConfig {
let base = GenValidConfig::portable_coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 0,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: false,
allow_v128: false,
allow_calls: false,
allow_relaxed_simd: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_const_expr_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
},
}
}
///|
pub fn GenValidConfig::wat_text_roundtrip_default() -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 3,
max_defined_funcs: 0,
max_params: 0,
max_results: 0,
max_locals: 0,
max_body_statements: 0,
max_body_depth: 0,
}
}
///|
pub enum GenValidProfile {
NaturalSmallProfile
NaturalWideProfile
NaturalDeepProfile
CoverageForcedPortableProfile
CoverageForcedAllFeaturesProfile
BinaryenOraclePortableProfile
BinaryenOracleRelaxedSimdProfile
MutationSeedSmallProfile
MutationSeedRichProfile
PassFuzzStressProfile
ValidatorStressProfile
PassCleanupProfile
OnceReductionTailCallsProfile
VacuumProfile
VacuumCoreProfile
VacuumTerminalUnreachableProfile
VacuumStructuralWrappersProfile
VacuumDroppedParentEffectsProfile
VacuumConstantResultIfProfile
VacuumCallPrefixContinuationProfile
VacuumLocalsetPrefixPreserveProfile
VacuumHazardBoundaryProfile
VacuumUnreadTeeProfile
RseAllProfile
RseCoreSameValueProfile
RseLocalCopySelfSetProfile
RseCfgMergeProfile
RseLoopFlowProfile
RseRefinedGetProfile
RseRefinementWrappersProfile
RseAggregateRefinalizeProfile
RseExceptionBoundariesProfile
RseHazardBoundaryProfile
RseVacuumTailProfile
PassDaeProfile
DaeAllProfile
ConstraintAllProfile
ConstraintIntegerProfile
ConstraintJoinsProfile
ConstraintLoopsProfile
ConstraintTeesProfile
ConstraintWraparoundProfile
ConstraintI64Profile
ConstraintLogicalProfile
ConstraintReferencesProfile
ConstraintUnreachableProfile
ConstraintRelationsProfile
ConstraintEffectsProfile
ConstraintFloatBoundaryProfile
Binaryen132ArrayMemoryProfile
Binaryen132WaitqueueProfile
Binaryen132CompactImportsProfile
Binaryen132AtomicOrdersProfile
Binaryen132DescriptorBranchesProfile
Dae2AllProfile
Dae2ForwardedResultsProfile
Dae2CyclesProfile
Dae2ControlFlowProfile
Dae2EffectfulArgumentsProfile
Dae2TupleResultsProfile
Dae2TailCallsProfile
Dae2IndirectProfile
Dae2OpenWorldProfile
Dae2ReferenceTypesProfile
Dae2LocalsProfile
Dae2ContinuationsProfile
Dae2ExceptionsProfile
Dae2CallRefProfile
Dae2IntrinsicsProfile
DaeUnusedParamsProfile
DaeEffectfulArgsProfile
DaeConstantArgsProfile
DaeUnusedReturnsProfile
DaeArgTypeRefinementProfile
DaeReturnTypeRefinementProfile
DaeUnseenCallBoundaryProfile
DaeTailCallBoundaryProfile
DaeLocalizationProfile
DaeConvergenceProfile
DaeOptimizingProfile
DaeOptimizingCoreProfile
DaeOptimizingManyTouchedProfile
DaeOptimizingMediumModuleProfile
DaeOptimizingLargeLocalsProfile
DaeOptimizingTouchedCallerProfile
DaeOptimizingForwardedSuffixProfile
DaeOptimizingResultControlProfile
DaeOptimizingStructuredLocalsProfile
DaeOptimizingReturnCleanupProfile
DaeOptimizingImmutableFieldProfile
DaeOptimizingComputedEffectsProfile
DaeOptimizingTableEffectsProfile
DaeOptimizingGcComputedProfile
DaeOptimizingTailBoundaryProfile
DaeOptimizingTypeReuseProfile
PassInliningProfile
InliningOptimizingDirectWrapperProfile
InliningOptimizingParamSpillProfile
InliningOptimizingReturnCallProfile
InliningOptimizingCleanupPayoffProfile
InliningOptimizingAllProfile
SgoInitializerFoldingProfile
SgoSameInitDeadSetProfile
SgoReadOnlyToWriteProfile
SgoStartupPropagationProfile
SgoRuntimePropagationProfile
SgoNestedCleanupProfile
SgoAllProfile
PggDirectGlobalProfile
PggCompoundGlobalProfile
PggGcCompoundProfile
PggDataOffsetProfile
PggElemOffsetProfile
PggAllProfile
PassMemoryProfile
PassGcRefProfile
PassControlProfile
NoImportsProfile
ImportsHeavyProfile
GcHeavyProfile
SimdHeavyProfile
RelaxedSimdProfile
MemoryHeavyProfile
ControlHeavyProfile
TopologyHeavyProfile
PathologicalValidProfile
EngineStateScalarControlProfile
EngineStateCallsProfile
EngineStateMemoryProfile
EngineStateTableProfile
EngineStateSimdProfile
EngineStateImportsProfile
EngineStateInitializationProfile
EngineStateTrapProfile
EngineStateMixedProfile
EngineStateTopologyProfile
EngineStateEffectsProfile
EngineStateResourcesProfile
EngineStateBoundariesProfile
EngineStateOptimizerShapesProfile
EngineStateEquivalentFamiliesProfile
EngineStatePassiveSegmentsProfile
EngineStateInstantiationBoundariesProfile
EngineStateMultiResourceProfile
EngineStateStackPressureProfile
EngineStateMemoryAliasingProfile
EngineStateIndirectTrapsProfile
EngineStateTrapPlacementProfile
EngineStateCrossInstanceProfile
EngineStateResourceExhaustionProfile
EngineStateDecoderTopologyProfile
EngineStateTailCallsProfile
EngineStateTypedFunctionReferencesProfile
EngineStateMemory64Profile
EngineStateExceptionsProfile
EngineStateGcProfile
EngineStateLinkGraphProfile
EngineStateGcGraphProfile
EngineStateInitializationGraphProfile
EngineStateExceptionUnwindProfile
EngineStateTypeCallMatrixProfile
EngineStateLebIndexBoundariesProfile
EngineStateTableReferenceMatrixProfile
EngineStateMemory64MultiMemoryProfile
EngineStateTrapCommitMatrixProfile
EngineStateMetamorphicTwinsProfile
EngineStateCompilerBoundariesProfile
EngineStateNanProfile
EngineStateInvalidModuleProfile
EngineStateRecursiveMultivalueProfile
EngineStateSubtypeCastGraphProfile
EngineStateAllProfile
EngineCompileShapesProfile
EngineProposalMatrixProfile
EngineStateCoreProfile
EngineTieringLoopProfile
EngineTieringLargeFunctionProfile
EngineTieringCallChainProfile
EngineTieringCallFanoutProfile
EngineTieringIndirectProfile
EngineTieringLocalsStackProfile
EngineTieringMemoryProfile
EngineTieringGcProfile
EngineTieringStressProfile
SemanticEffectsProfile
SemanticImportEventsProfile
SemanticTrapFrontierProfile
SemanticResourcesProfile
SemanticOptimizerAllProfile
GsiDescCastPositiveProfile
GsiDescCastZeroBoundaryProfile
GsiDescCastMultiBoundaryProfile
GsiDescCastStrictSubtypeProfile
GsiDescCastUnreachableBoundaryProfile
GsiDescCastAllProfile
PrecomputeScalarProfile
PrecomputeScalarValueProfile
PrecomputeGcValueProfile
PrecomputeEffectfulValueProfile
PrecomputeControlProfile
PrecomputeGlobalProfile
PrecomputeDropCleanupProfile
PrecomputeEffectBoundaryProfile
PrecomputeGcAtomicBoundaryProfile
PrecomputeDirectPrefixWatchProfile
PrecomputePropagateLocalFactsProfile
PrecomputeAllProfile
PickLoadSignsSignedExtendProfile
PickLoadSignsSignedShiftProfile
PickLoadSignsUnsignedMaskProfile
PickLoadSignsUnsignedShiftProfile
PickLoadSignsUnknownUseBoundaryProfile
PickLoadSignsMixedWidthBoundaryProfile
PickLoadSignsWidthMismatchBoundaryProfile
PickLoadSignsTeeBoundaryProfile
PickLoadSignsNoMemoryBoundaryProfile
PickLoadSignsImportedMemoryProfile
PickLoadSignsI64WatchProfile
PickLoadSignsAllProfile
CodePushingIfArmProfile
CodePushingAfterIfProfile
CodePushingDroppedIfProfile
CodePushingBrIfProfile
CodePushingBrOnNullProfile
CodePushingBrOnNonNullProfile
CodePushingBrOnNonNullPrefixProfile
CodePushingBrOnCastProfile
CodePushingBrOnCastFailProfile
CodePushingBrIfValueProfile
CodePushingMultiSetProfile
CodePushingMultiSetDroppedIfProfile
CodePushingMultiSetBrIfProfile
CodePushingMultiSetLocalCopyProfile
CodePushingMultiSetNopWindowProfile
CodePushingLoopBrIfProfile
CodePushingMultiSetDropWindowProfile
CodePushingMultiSetLocalGetWindowProfile
CodePushingMultiSetGlobalGetWindowProfile
CodePushingZeroReadProfile
CodePushingAllProfile
MergeBlocksStructuralProfile
MergeBlocksExpressionProfile
MergeBlocksEffectProfile
MergeBlocksEhAtomicProfile
MergeBlocksAllProfile
CodeFoldingIfArmsProfile
CodeFoldingBlockExitsProfile
CodeFoldingReturnsProfile
CodeFoldingTailCallsProfile
CodeFoldingMovementProfile
CodeFoldingEhProfile
CodeFoldingAllProfile
TupleOptimizationSpillProfile
TupleOptimizationCopyChainProfile
TupleOptimizationTeeProfile
TupleOptimizationAliasCapturesProfile
TupleOptimizationAllProfile
DeadCodeEliminationNonControlProfile
DeadCodeEliminationBlockSuffixProfile
DeadCodeEliminationIfBothArmsProfile
DeadCodeEliminationIfConditionProfile
DeadCodeEliminationLoopBodyProfile
DeadCodeEliminationTryTableProfile
DeadCodeEliminationTryTableCatchRefProfile
DeadCodeEliminationBranchPayloadForwarderProfile
DeadCodeEliminationPrefixBranchPayloadProfile
DeadCodeEliminationSplitLocalSetWrapperProfile
DeadCodeEliminationStructuredPrefixProfile
DeadCodeEliminationEffectfulStructuredPrefixProfile
DeadCodeEliminationAllProfile
HsoTeeProfile
HsoChainProfile
HsoDefaultProfile
HsoSideEffectsProfile
HsoDescriptorProfile
HsoControlFlowProfile
HsoSwapProfile
HsoSharedOrderingProfile
HsoBoundariesProfile
HeapStoreOptimizationProfile
MemoryPackingActiveRangesProfile
MemoryPackingActiveTrapsProfile
MemoryPackingDefinedOverlapProfile
MemoryPackingPassiveSplitsProfile
MemoryPackingSegmentOpsProfile
MemoryPackingMemory64Profile
MemoryPackingBoundariesProfile
MemoryPackingImportedOverlapProfile
MemoryPackingAllProfile
Heap2LocalStructProfile
Heap2LocalArrayProfile
Heap2LocalRefProfile
Heap2LocalOwnerUpdatesProfile
Heap2LocalAllProfile
LocalSubtypingStraightLineProfile
LocalSubtypingStructuredProfile
LocalSubtypingUnreachableTailProfile
LocalSubtypingLubsProfile
LocalSubtypingIterationProfile
LocalSubtypingNullBottomProfile
LocalSubtypingControlRefinalizeProfile
LocalSubtypingAllProfile
CoalesceLocalsStraightLineProfile
CoalesceLocalsStructuredProfile
CoalesceLocalsLoopCopyThroughProfile
CoalesceLocalsEntryValuesProfile
CoalesceLocalsCopyPreferenceProfile
CoalesceLocalsTeeCopiesProfile
CoalesceLocalsInterBlockProfile
CoalesceLocalsUnreachableProfile
CoalesceLocalsLegacyEhProfile
CoalesceLocalsLargeUnusedProfile
CoalesceLocalsExactTypesProfile
CoalesceLocalsAllProfile
MergeLocalsForwardProfile
MergeLocalsForwardMultipleProfile
MergeLocalsPartialInfluenceProfile
MergeLocalsReverseProfile
MergeLocalsReverseBoundaryProfile
MergeLocalsControlProfile
MergeLocalsTeeProfile
MergeLocalsMergeBoundaryProfile
MergeLocalsTypeBoundaryProfile
MergeLocalsRollbackProfile
MergeLocalsReverseRollbackProfile
MergeLocalsNestedCopiesProfile
MergeLocalsTrivialConfusionProfile
MergeLocalsUnreachableProfile
MergeLocalsLegacyEhProfile
MergeLocalsAllProfile
RemoveUnusedBrsControlProfile
RemoveUnusedBrsSwitchProfile
RemoveUnusedBrsGcProfile
RemoveUnusedBrsCleanupProfile
RemoveUnusedBrsConstantBrIfProfile
RemoveUnusedBrsSingleTargetBrTableProfile
RemoveUnusedBrsMultiFunctionProfile
RemoveUnusedBrsResultRefinalizeProfile
RemoveUnusedBrsMultivalueDropProfile
RemoveUnusedBrsWrapperCleanupProfile
RemoveUnusedBrsSelectifyProfile
RemoveUnusedBrsTailFlowProfile
RemoveUnusedBrsOneArmIfProfile
RemoveUnusedBrsLoopProfile
RemoveUnusedBrsSinkBlocksProfile
RemoveUnusedBrsEhProfile
RemoveUnusedBrsJumpThreadProfile
RemoveUnusedBrsTablifyProfile
RemoveUnusedBrsOptimizeSetIfProfile
RemoveUnusedBrsRestructureIfProfile
RemoveUnusedBrsAdjacentBranchProfile
RemoveUnusedBrsWinBoundaryProfile
RemoveUnusedBrsAllProfile
DuplicateImportEliminationFunctionsProfile
DuplicateImportEliminationIdentityProfile
DuplicateImportEliminationModuleCodeProfile
DuplicateImportEliminationLegacyEhProfile
DuplicateImportEliminationNonfunctionProfile
DuplicateImportEliminationAllProfile
LocalCseTriggerProfile
DuplicateFunctionEliminationTriggerProfile
MergeSimilarFunctionsLiteralsProfile
MergeSimilarFunctionsRepeatedDiffProfile
MergeSimilarFunctionsExactDuplicatesProfile
MergeSimilarFunctionsDuplicateTypesProfile
MergeSimilarFunctionsLocalsProfile
MergeSimilarFunctionsNestedProfile
MergeSimilarFunctionsCallTargetsProfile
MergeSimilarFunctionsTailCallsProfile
MergeSimilarFunctionsRecordCopyProfile
MergeSimilarFunctionsAllProfile
SsaNomergeCoverageProfile
SsaNomergeSmokeProfile
SsaNomergeParityProfile
SsaNomergeStressProfile
SsaNomergeAllProfile
SsaFreshSetProfile
SsaFreshTeeProfile
SsaParamEntryProfile
SsaDefaultNumericProfile
SsaDefaultRefProfile
SsaUnreachableProfile
SsaMergeExplicitProfile
SsaMergeParamEntryProfile
SsaMergeDefaultEntryProfile
SsaMergeSharedSetsProfile
SsaLoopProfile
SsaBranchProfile
SsaTypedControlProfile
SsaNestedValueProfile
SsaEhProfile
SsaAllProfile
SimplifyLocalsLocalTrafficProfile
SimplifyLocalsStructureResultProfile
SimplifyLocalsFlatParentProfile
SimplifyLocalsEffectOrderProfile
SimplifyLocalsStressProfile
SimplifyLocalsFamilyCoverageProfile
SimplifyLocalsAllProfile
SimplifyLocalsNoteeAllProfile
SimplifyLocalsNoteeNostructureAllProfile
SimplifyLocalsNonestingAllProfile
SimplifyLocalsNostructureStraightLineProfile
SimplifyLocalsNostructureTeeControlProfile
SimplifyLocalsNostructureEffectOrderProfile
SimplifyLocalsNostructureAllProfile
ReorderLocalsHotSortProfile
ReorderLocalsPermutationOnlyProfile
ReorderLocalsFirstUseTiesProfile
ReorderLocalsMixedTypesProfile
ReorderLocalsReferenceTypesProfile
ReorderLocalsUnusedTrimProfile
ReorderLocalsStructuredProfile
ReorderLocalsLegacyEhProfile
ReorderLocalsMultiFunctionProfile
ReorderLocalsNameRepairProfile
ReorderLocalsAllProfile
OptimizeCastsLaterReuseProfile
OptimizeCastsEarlyMotionProfile
OptimizeCastsBarriersProfile
OptimizeCastsBestCastProfile
OptimizeCastsRefAsProfile
OptimizeCastsStaticFoldsProfile
OptimizeCastsNeighborhoodProfile
OptimizeCastsAllProfile
PassOiDefaultScalarProfile
PassOiLocalFactsProfile
PassOiBooleanSelectProfile
PassOiMemoryBulkProfile
PassOiCallRefProfile
PassOiRefGcProfile
PassOiGcAggregateProfile
PassOiDescriptorGcProfile
PassOiTupleProfile
PassOiAllProfile
FlattenFunctionResultsProfile
FlattenOperandsProfile
FlattenBlocksProfile
FlattenIfsProfile
FlattenLoopsProfile
FlattenTeeProfile
FlattenBrProfile
FlattenBrIfProfile
FlattenBrTableProfile
FlattenUnreachableProfile
FlattenMultivalueProfile
FlattenLegacyEhProfile
FlattenAllProfile
DirectizeConstantProfile
DirectizeSelectProfile
DirectizeTableFactsProfile
DirectizeTailCallProfile
DirectizeGcProfile
DirectizeTable64Profile
DirectizeLegacyEhProfile
DirectizeBoundaryProfile
DirectizeAllProfile
RandomAllProfilesProfile
CampaignMemory64MultiMemoryProfile
CampaignEhControlProfile
CampaignGcRefSubtypesProfile
CampaignSimdNumericProfile
CampaignCallTopologyProfile
CampaignSegmentStateProfile
RumeDeadGraphProfile
RumeTableTrapProfile
RumeLegacyEhProfile
RumeSpecialImportsProfile
RumeCallableReferencesProfile
RumeContinuationsDescriptorsProfile
RumeIndexRemapStressProfile
RumeAllProfile
ReorderGlobalsHotTrafficProfile
ReorderGlobalsDependencySearchProfile
ReorderGlobalsImportedProfile
ReorderGlobalsModuleCodeProfile
ReorderGlobalsLegacyEhProfile
ReorderGlobalsMetadataRemapProfile
ReorderGlobalsThresholdProfile
ReorderGlobalsAllProfile
GlobalRefiningPrivateWritesProfile
GlobalRefiningExportBoundariesProfile
GlobalRefiningImportAliasesProfile
GlobalRefiningSubtypeJoinsProfile
GlobalRefiningAllProfile
} derive(Eq, Debug)
///|
pub struct GenValidProfileMember {
profile : GenValidProfile
weight : Int32
} derive(Eq, Debug)
///|
pub fn GenValidProfileMember::new(
profile : GenValidProfile,
weight : Int32,
) -> GenValidProfileMember {
{ profile, weight, }
}
///|
pub fn gen_valid_profile_name(profile : GenValidProfile) -> String {
match profile {
NaturalSmallProfile => "natural-small"
NaturalWideProfile => "natural-wide"
NaturalDeepProfile => "natural-deep"
CoverageForcedPortableProfile => "coverage-forced-portable"
CoverageForcedAllFeaturesProfile => "coverage-forced-all-features"
BinaryenOraclePortableProfile => "binaryen-oracle-portable"
BinaryenOracleRelaxedSimdProfile => "binaryen-oracle-relaxed-simd"
MutationSeedSmallProfile => "mutation-seed-small"
MutationSeedRichProfile => "mutation-seed-rich"
PassFuzzStressProfile => "pass-fuzz-stress"
ValidatorStressProfile => "validator-stress"
PassCleanupProfile => "pass-cleanup"
OnceReductionTailCallsProfile => "once-reduction-tail-calls"
VacuumProfile => "vacuum"
VacuumCoreProfile => "vacuum-core"
VacuumTerminalUnreachableProfile => "vacuum-terminal-unreachable"
VacuumStructuralWrappersProfile => "vacuum-structural-wrappers"
VacuumDroppedParentEffectsProfile => "vacuum-dropped-parent-effects"
VacuumConstantResultIfProfile => "vacuum-constant-result-if"
VacuumCallPrefixContinuationProfile => "vacuum-call-prefix-continuation"
VacuumLocalsetPrefixPreserveProfile => "vacuum-localset-prefix-preserve"
VacuumHazardBoundaryProfile => "vacuum-hazard-boundary"
VacuumUnreadTeeProfile => "vacuum-unread-tee"
RseAllProfile => "rse"
RseCoreSameValueProfile => "rse-core-same-value"
RseLocalCopySelfSetProfile => "rse-local-copy-self-set"
RseCfgMergeProfile => "rse-cfg-merge"
RseLoopFlowProfile => "rse-loop-flow"
RseRefinedGetProfile => "rse-refined-get"
RseRefinementWrappersProfile => "rse-refinement-wrappers"
RseAggregateRefinalizeProfile => "rse-aggregate-refinalize"
RseExceptionBoundariesProfile => "rse-exception-boundaries"
RseHazardBoundaryProfile => "rse-hazard-boundary"
RseVacuumTailProfile => "rse-vacuum-tail"
PassDaeProfile => "pass-dae"
DaeAllProfile => "dead-argument-elimination"
ConstraintAllProfile => "constraint-analysis"
ConstraintIntegerProfile => "constraint-integer"
ConstraintJoinsProfile => "constraint-joins"
ConstraintLoopsProfile => "constraint-loops"
ConstraintTeesProfile => "constraint-tees"
ConstraintWraparoundProfile => "constraint-wraparound"
ConstraintI64Profile => "constraint-i64"
ConstraintLogicalProfile => "constraint-logical"
ConstraintReferencesProfile => "constraint-references"
ConstraintUnreachableProfile => "constraint-unreachable"
ConstraintRelationsProfile => "constraint-relations"
ConstraintEffectsProfile => "constraint-effects"
ConstraintFloatBoundaryProfile => "constraint-float-boundary"
Dae2AllProfile => "dae2"
Dae2ForwardedResultsProfile => "dae2-forwarded-results"
Dae2CyclesProfile => "dae2-cycles"
Dae2ControlFlowProfile => "dae2-control-flow"
Dae2EffectfulArgumentsProfile => "dae2-effectful-arguments"
Dae2TupleResultsProfile => "dae2-tuple-results"
Dae2TailCallsProfile => "dae2-tail-calls"
Dae2IndirectProfile => "dae2-indirect"
Dae2OpenWorldProfile => "dae2-open-world"
Dae2ReferenceTypesProfile => "dae2-reference-types"
Binaryen132ArrayMemoryProfile => "binaryen132-array-memory"
Binaryen132WaitqueueProfile => "binaryen132-waitqueue"
Binaryen132AtomicOrdersProfile => "binaryen132-atomic-orders"
Binaryen132DescriptorBranchesProfile => "binaryen132-descriptor-branches"
Binaryen132CompactImportsProfile => "binaryen132-compact-imports"
Dae2LocalsProfile => "dae2-locals"
Dae2ContinuationsProfile => "dae2-continuations"
Dae2ExceptionsProfile => "dae2-exceptions"
Dae2CallRefProfile => "dae2-call-ref"
Dae2IntrinsicsProfile => "dae2-intrinsics"
DaeUnusedParamsProfile => "dae-unused-params"
DaeEffectfulArgsProfile => "dae-effectful-args"
DaeConstantArgsProfile => "dae-constant-args"
DaeUnusedReturnsProfile => "dae-unused-returns"
DaeArgTypeRefinementProfile => "dae-arg-type-refinement"
DaeReturnTypeRefinementProfile => "dae-return-type-refinement"
DaeUnseenCallBoundaryProfile => "dae-unseen-call-boundary"
DaeTailCallBoundaryProfile => "dae-tail-call-boundary"
DaeLocalizationProfile => "dae-localization"
DaeConvergenceProfile => "dae-convergence"
DaeOptimizingProfile => "dae-optimizing"
DaeOptimizingCoreProfile => "dae-optimizing-core"
DaeOptimizingManyTouchedProfile => "dae-optimizing-many-touched"
DaeOptimizingMediumModuleProfile => "dae-optimizing-medium-module"
DaeOptimizingLargeLocalsProfile => "dae-optimizing-large-locals"
DaeOptimizingTouchedCallerProfile => "dae-optimizing-touched-caller"
DaeOptimizingForwardedSuffixProfile => "dae-optimizing-forwarded-suffix"
DaeOptimizingResultControlProfile => "dae-optimizing-result-control"
DaeOptimizingStructuredLocalsProfile => "dae-optimizing-structured-locals"
DaeOptimizingReturnCleanupProfile => "dae-optimizing-return-cleanup"
DaeOptimizingImmutableFieldProfile => "dae-optimizing-immutable-field"
DaeOptimizingComputedEffectsProfile => "dae-optimizing-computed-effects"
DaeOptimizingTableEffectsProfile => "dae-optimizing-table-effects"
DaeOptimizingGcComputedProfile => "dae-optimizing-gc-computed"
DaeOptimizingTailBoundaryProfile => "dae-optimizing-tail-boundary"
DaeOptimizingTypeReuseProfile => "dae-optimizing-type-reuse"
PassInliningProfile => "pass-inlining"
InliningOptimizingDirectWrapperProfile =>
"inlining-optimizing-direct-wrapper"
InliningOptimizingParamSpillProfile => "inlining-optimizing-param-spill"
InliningOptimizingReturnCallProfile => "inlining-optimizing-return-call"
InliningOptimizingCleanupPayoffProfile =>
"inlining-optimizing-cleanup-payoff"
InliningOptimizingAllProfile => "inlining-optimizing-all"
SgoInitializerFoldingProfile =>
"simplify-globals-optimizing-initializer-folding"
SgoSameInitDeadSetProfile =>
"simplify-globals-optimizing-same-init-dead-set"
SgoReadOnlyToWriteProfile =>
"simplify-globals-optimizing-read-only-to-write"
SgoStartupPropagationProfile =>
"simplify-globals-optimizing-startup-propagation"
SgoRuntimePropagationProfile =>
"simplify-globals-optimizing-runtime-propagation"
SgoNestedCleanupProfile => "simplify-globals-optimizing-nested-cleanup"
SgoAllProfile => "simplify-globals-optimizing-all"
PggDirectGlobalProfile => "propagate-globals-globally-direct-global"
PggCompoundGlobalProfile => "propagate-globals-globally-compound-global"
PggGcCompoundProfile => "propagate-globals-globally-gc-compound"
PggDataOffsetProfile => "propagate-globals-globally-data-offset"
PggElemOffsetProfile => "propagate-globals-globally-elem-offset"
PggAllProfile => "propagate-globals-globally-all"
PassMemoryProfile => "pass-memory"
PassGcRefProfile => "pass-gc-ref"
PassControlProfile => "pass-control"
NoImportsProfile => "no-imports"
ImportsHeavyProfile => "imports-heavy"
GcHeavyProfile => "gc-heavy"
SimdHeavyProfile => "simd-heavy"
RelaxedSimdProfile => "relaxed-simd"
MemoryHeavyProfile => "memory-heavy"
ControlHeavyProfile => "control-heavy"
TopologyHeavyProfile => "topology-heavy"
PathologicalValidProfile => "pathological-valid"
EngineStateScalarControlProfile => "engine-state-scalar-control"
EngineStateCallsProfile => "engine-state-calls"
EngineStateMemoryProfile => "engine-state-memory"
EngineStateTableProfile => "engine-state-table"
EngineStateSimdProfile => "engine-state-simd"
EngineStateImportsProfile => "engine-state-imports"
EngineStateInitializationProfile => "engine-state-initialization"
EngineStateTrapProfile => "engine-state-trap"
EngineStateMixedProfile => "engine-state-mixed"
EngineStateTopologyProfile => "engine-state-topology"
EngineStateEffectsProfile => "engine-state-effects"
EngineStateResourcesProfile => "engine-state-resources"
EngineStateBoundariesProfile => "engine-state-boundaries"
EngineStateOptimizerShapesProfile => "engine-state-optimizer-shapes"
EngineStateEquivalentFamiliesProfile => "engine-state-equivalent-families"
EngineStatePassiveSegmentsProfile => "engine-state-passive-segments"
EngineStateInstantiationBoundariesProfile =>
"engine-state-instantiation-boundaries"
EngineStateMultiResourceProfile => "engine-state-multi-resource"
EngineStateStackPressureProfile => "engine-state-stack-pressure"
EngineStateMemoryAliasingProfile => "engine-state-memory-aliasing"
EngineStateIndirectTrapsProfile => "engine-state-indirect-traps"
EngineStateTrapPlacementProfile => "engine-state-trap-placement"
EngineStateCrossInstanceProfile => "engine-state-cross-instance"
EngineStateResourceExhaustionProfile => "engine-state-resource-exhaustion"
EngineStateDecoderTopologyProfile => "engine-state-decoder-topology"
EngineStateTailCallsProfile => "engine-state-tail-calls"
EngineStateTypedFunctionReferencesProfile =>
"engine-state-typed-function-references"
EngineStateMemory64Profile => "engine-state-memory64"
EngineStateExceptionsProfile => "engine-state-exceptions"
EngineStateGcProfile => "engine-state-gc"
EngineStateLinkGraphProfile => "engine-state-link-graph"
EngineStateGcGraphProfile => "engine-state-gc-graph"
EngineStateInitializationGraphProfile => "engine-state-initialization-graph"
EngineStateExceptionUnwindProfile => "engine-state-exception-unwind"
EngineStateTypeCallMatrixProfile => "engine-state-type-call-matrix"
EngineStateLebIndexBoundariesProfile => "engine-state-leb-index-boundaries"
EngineStateTableReferenceMatrixProfile =>
"engine-state-table-reference-matrix"
EngineStateMemory64MultiMemoryProfile =>
"engine-state-memory64-multi-memory"
EngineStateTrapCommitMatrixProfile => "engine-state-trap-commit-matrix"
EngineStateMetamorphicTwinsProfile => "engine-state-metamorphic-twins"
EngineStateCompilerBoundariesProfile => "engine-state-compiler-boundaries"
EngineStateNanProfile => "engine-state-nan"
EngineStateInvalidModuleProfile => "engine-state-invalid-module"
EngineStateRecursiveMultivalueProfile => "engine-state-recursive-multivalue"
EngineStateSubtypeCastGraphProfile => "engine-state-subtype-cast-graph"
EngineStateAllProfile => "engine-state-all"
EngineCompileShapesProfile => "engine-compile-shapes"
EngineProposalMatrixProfile => "engine-proposal-matrix"
EngineStateCoreProfile => "engine-state-core"
EngineTieringLoopProfile => "engine-tiering-loop"
EngineTieringLargeFunctionProfile => "engine-tiering-large-function"
EngineTieringCallChainProfile => "engine-tiering-call-chain"
EngineTieringCallFanoutProfile => "engine-tiering-call-fanout"
EngineTieringIndirectProfile => "engine-tiering-indirect"
EngineTieringLocalsStackProfile => "engine-tiering-locals-stack"
EngineTieringMemoryProfile => "engine-tiering-memory"
EngineTieringGcProfile => "engine-tiering-gc"
EngineTieringStressProfile => "engine-tiering-stress"
SemanticEffectsProfile => "semantic-effects"
SemanticImportEventsProfile => "semantic-import-events"
SemanticTrapFrontierProfile => "semantic-trap-frontier"
SemanticResourcesProfile => "semantic-resources"
SemanticOptimizerAllProfile => "semantic-optimizer-all"
GsiDescCastPositiveProfile => "gsi-desc-cast-positive"
GsiDescCastZeroBoundaryProfile => "gsi-desc-cast-zero-boundary"
GsiDescCastMultiBoundaryProfile => "gsi-desc-cast-multi-boundary"
GsiDescCastStrictSubtypeProfile => "gsi-desc-cast-strict-subtype"
GsiDescCastUnreachableBoundaryProfile =>
"gsi-desc-cast-unreachable-boundary"
GsiDescCastAllProfile => "gsi-desc-cast"
PrecomputeScalarProfile => "precompute-scalar"
PrecomputeScalarValueProfile => "precompute-scalar-values"
PrecomputeGcValueProfile => "precompute-gc-values"
PrecomputeEffectfulValueProfile => "precompute-effectful-values"
PrecomputeControlProfile => "precompute-control"
PrecomputeGlobalProfile => "precompute-global"
PrecomputeDropCleanupProfile => "precompute-drop-cleanup"
PrecomputeEffectBoundaryProfile => "precompute-effect-boundary"
PrecomputeGcAtomicBoundaryProfile => "precompute-gc-atomic-boundary"
PrecomputeDirectPrefixWatchProfile => "precompute-direct-prefix-watch"
PrecomputePropagateLocalFactsProfile => "precompute-propagate-local-facts"
PrecomputeAllProfile => "precompute-all"
PickLoadSignsSignedExtendProfile => "pick-load-signs-signed-extend"
PickLoadSignsSignedShiftProfile => "pick-load-signs-signed-shift"
PickLoadSignsUnsignedMaskProfile => "pick-load-signs-unsigned-mask"
PickLoadSignsUnsignedShiftProfile => "pick-load-signs-unsigned-shift"
PickLoadSignsUnknownUseBoundaryProfile =>
"pick-load-signs-unknown-use-boundary"
PickLoadSignsMixedWidthBoundaryProfile =>
"pick-load-signs-mixed-width-boundary"
PickLoadSignsWidthMismatchBoundaryProfile =>
"pick-load-signs-width-mismatch-boundary"
PickLoadSignsTeeBoundaryProfile => "pick-load-signs-tee-boundary"
PickLoadSignsNoMemoryBoundaryProfile => "pick-load-signs-no-memory-boundary"
PickLoadSignsImportedMemoryProfile => "pick-load-signs-imported-memory"
PickLoadSignsI64WatchProfile => "pick-load-signs-i64-watch"
PickLoadSignsAllProfile => "pick-load-signs-all"
CodePushingIfArmProfile => "code-pushing-if-arm"
CodePushingAfterIfProfile => "code-pushing-after-if"
CodePushingDroppedIfProfile => "code-pushing-dropped-if"
CodePushingBrIfProfile => "code-pushing-br-if"
CodePushingBrOnNullProfile => "code-pushing-br-on-null"
CodePushingBrOnNonNullProfile => "code-pushing-br-on-non-null"
CodePushingBrOnNonNullPrefixProfile => "code-pushing-br-on-non-null-prefix"
CodePushingBrOnCastProfile => "code-pushing-br-on-cast"
CodePushingBrOnCastFailProfile => "code-pushing-br-on-cast-fail"
CodePushingBrIfValueProfile => "code-pushing-br-if-value"
CodePushingMultiSetProfile => "code-pushing-multi-set"
CodePushingMultiSetDroppedIfProfile => "code-pushing-multi-set-dropped-if"
CodePushingMultiSetBrIfProfile => "code-pushing-multi-set-br-if"
CodePushingMultiSetLocalCopyProfile => "code-pushing-multi-set-local-copy"
CodePushingMultiSetNopWindowProfile => "code-pushing-multi-set-nop-window"
CodePushingLoopBrIfProfile => "code-pushing-loop-br-if"
CodePushingMultiSetDropWindowProfile => "code-pushing-multi-set-drop-window"
CodePushingMultiSetLocalGetWindowProfile =>
"code-pushing-multi-set-local-get-window"
CodePushingMultiSetGlobalGetWindowProfile =>
"code-pushing-multi-set-global-get-window"
CodePushingZeroReadProfile => "code-pushing-zero-read"
CodePushingAllProfile => "code-pushing-all"
MergeBlocksStructuralProfile => "merge-blocks-structural"
MergeBlocksExpressionProfile => "merge-blocks-expression"
MergeBlocksEffectProfile => "merge-blocks-effect-order"
MergeBlocksEhAtomicProfile => "merge-blocks-eh-atomic"
MergeBlocksAllProfile => "merge-blocks-all"
RumeDeadGraphProfile => "rume-dead-graph"
RumeTableTrapProfile => "rume-table-trap"
RumeLegacyEhProfile => "rume-legacy-eh"
RumeSpecialImportsProfile => "rume-special-imports"
RumeCallableReferencesProfile => "rume-callable-references"
RumeContinuationsDescriptorsProfile => "rume-continuations-descriptors"
RumeIndexRemapStressProfile => "rume-index-remap-stress"
RumeAllProfile => "rume-all"
ReorderGlobalsHotTrafficProfile => "reorder-globals-hot-traffic"
ReorderGlobalsDependencySearchProfile => "reorder-globals-dependency-search"
ReorderGlobalsImportedProfile => "reorder-globals-imported"
ReorderGlobalsModuleCodeProfile => "reorder-globals-module-code"
ReorderGlobalsLegacyEhProfile => "reorder-globals-legacy-eh"
ReorderGlobalsMetadataRemapProfile => "reorder-globals-metadata-remap"
ReorderGlobalsThresholdProfile => "reorder-globals-threshold"
ReorderGlobalsAllProfile => "reorder-globals-all"
GlobalRefiningPrivateWritesProfile => "global-refining-private-writes"
GlobalRefiningExportBoundariesProfile => "global-refining-export-boundaries"
GlobalRefiningImportAliasesProfile => "global-refining-import-aliases"
GlobalRefiningSubtypeJoinsProfile => "global-refining-subtype-joins"
GlobalRefiningAllProfile => "global-refining-all"
CodeFoldingIfArmsProfile => "code-folding-if-arms"
CodeFoldingBlockExitsProfile => "code-folding-block-exits"
CodeFoldingReturnsProfile => "code-folding-returns"
CodeFoldingTailCallsProfile => "code-folding-tail-calls"
CodeFoldingMovementProfile => "code-folding-movement"
CodeFoldingEhProfile => "code-folding-eh"
CodeFoldingAllProfile => "code-folding-all"
TupleOptimizationSpillProfile => "tuple-optimization-spill"
TupleOptimizationCopyChainProfile => "tuple-optimization-copy-chain"
TupleOptimizationTeeProfile => "tuple-optimization-tee"
TupleOptimizationAliasCapturesProfile => "tuple-optimization-alias-captures"
TupleOptimizationAllProfile => "tuple-optimization-all"
DeadCodeEliminationNonControlProfile => "dead-code-elimination-non-control"
DeadCodeEliminationBlockSuffixProfile =>
"dead-code-elimination-block-suffix"
DeadCodeEliminationIfBothArmsProfile => "dead-code-elimination-if-both-arms"
DeadCodeEliminationIfConditionProfile =>
"dead-code-elimination-if-condition"
DeadCodeEliminationLoopBodyProfile => "dead-code-elimination-loop-body"
DeadCodeEliminationTryTableProfile => "dead-code-elimination-try-table"
DeadCodeEliminationTryTableCatchRefProfile =>
"dead-code-elimination-try-table-catch-ref"
DeadCodeEliminationBranchPayloadForwarderProfile =>
"dead-code-elimination-branch-payload-forwarder"
DeadCodeEliminationPrefixBranchPayloadProfile =>
"dead-code-elimination-prefix-branch-payload"
DeadCodeEliminationSplitLocalSetWrapperProfile =>
"dead-code-elimination-split-local-set-wrapper"
DeadCodeEliminationStructuredPrefixProfile =>
"dead-code-elimination-structured-prefix"
DeadCodeEliminationEffectfulStructuredPrefixProfile =>
"dead-code-elimination-effectful-structured-prefix"
DeadCodeEliminationAllProfile => "dead-code-elimination-all"
HsoTeeProfile => "heap-store-optimization-tee"
HsoChainProfile => "heap-store-optimization-chains"
HsoDefaultProfile => "heap-store-optimization-defaults"
HsoSideEffectsProfile => "heap-store-optimization-side-effects"
HsoDescriptorProfile => "heap-store-optimization-descriptors"
HsoControlFlowProfile => "heap-store-optimization-control-flow"
HsoSwapProfile => "heap-store-optimization-swaps"
HsoSharedOrderingProfile => "heap-store-optimization-shared-ordering"
HsoBoundariesProfile => "heap-store-optimization-boundaries"
HeapStoreOptimizationProfile => "heap-store-optimization"
MemoryPackingActiveRangesProfile => "memory-packing-active-ranges"
MemoryPackingActiveTrapsProfile => "memory-packing-active-traps"
MemoryPackingDefinedOverlapProfile => "memory-packing-defined-overlap"
MemoryPackingPassiveSplitsProfile => "memory-packing-passive-splits"
MemoryPackingSegmentOpsProfile => "memory-packing-segment-ops"
MemoryPackingMemory64Profile => "memory-packing-memory64"
MemoryPackingBoundariesProfile => "memory-packing-boundaries"
MemoryPackingImportedOverlapProfile => "memory-packing-imported-overlap"
MemoryPackingAllProfile => "memory-packing-all"
Heap2LocalStructProfile => "heap2local-struct"
Heap2LocalArrayProfile => "heap2local-array"
Heap2LocalRefProfile => "heap2local-ref"
Heap2LocalOwnerUpdatesProfile => "heap2local-owner-updates"
Heap2LocalAllProfile => "heap2local-all"
LocalSubtypingStraightLineProfile => "local-subtyping-straight-line"
LocalSubtypingStructuredProfile => "local-subtyping-structured"
LocalSubtypingUnreachableTailProfile => "local-subtyping-unreachable-tail"
LocalSubtypingLubsProfile => "local-subtyping-lubs"
LocalSubtypingIterationProfile => "local-subtyping-iteration"
LocalSubtypingNullBottomProfile => "local-subtyping-null-bottom"
LocalSubtypingControlRefinalizeProfile =>
"local-subtyping-control-refinalize"
LocalSubtypingAllProfile => "local-subtyping-all"
CoalesceLocalsStraightLineProfile => "coalesce-locals-straight-line"
CoalesceLocalsStructuredProfile => "coalesce-locals-structured"
CoalesceLocalsLoopCopyThroughProfile => "coalesce-locals-loop-copy-through"
CoalesceLocalsEntryValuesProfile => "coalesce-locals-entry-values"
CoalesceLocalsCopyPreferenceProfile => "coalesce-locals-copy-preference"
CoalesceLocalsTeeCopiesProfile => "coalesce-locals-tee-copies"
CoalesceLocalsInterBlockProfile => "coalesce-locals-inter-block"
CoalesceLocalsUnreachableProfile => "coalesce-locals-unreachable"
CoalesceLocalsLegacyEhProfile => "coalesce-locals-legacy-eh"
CoalesceLocalsLargeUnusedProfile => "coalesce-locals-large-unused"
CoalesceLocalsExactTypesProfile => "coalesce-locals-exact-types"
CoalesceLocalsAllProfile => "coalesce-locals-all"
MergeLocalsForwardProfile => "merge-locals-forward"
MergeLocalsForwardMultipleProfile => "merge-locals-forward-multiple"
MergeLocalsPartialInfluenceProfile => "merge-locals-partial-influence"
MergeLocalsReverseProfile => "merge-locals-reverse"
MergeLocalsReverseBoundaryProfile => "merge-locals-reverse-boundary"
MergeLocalsControlProfile => "merge-locals-control"
MergeLocalsTeeProfile => "merge-locals-tee"
MergeLocalsMergeBoundaryProfile => "merge-locals-merge-boundary"
MergeLocalsTypeBoundaryProfile => "merge-locals-type-boundary"
MergeLocalsRollbackProfile => "merge-locals-rollback"
MergeLocalsReverseRollbackProfile => "merge-locals-reverse-rollback"
MergeLocalsNestedCopiesProfile => "merge-locals-nested-copies"
MergeLocalsTrivialConfusionProfile => "merge-locals-trivial-confusion"
MergeLocalsUnreachableProfile => "merge-locals-unreachable"
MergeLocalsLegacyEhProfile => "merge-locals-legacy-eh"
MergeLocalsAllProfile => "merge-locals-all"
RemoveUnusedBrsControlProfile => "remove-unused-brs-control"
RemoveUnusedBrsSwitchProfile => "remove-unused-brs-switch"
RemoveUnusedBrsGcProfile => "remove-unused-brs-gc"
RemoveUnusedBrsCleanupProfile => "remove-unused-brs-cleanup"
RemoveUnusedBrsConstantBrIfProfile => "remove-unused-brs-constant-br-if"
RemoveUnusedBrsSingleTargetBrTableProfile =>
"remove-unused-brs-single-target-br-table"
RemoveUnusedBrsMultiFunctionProfile => "remove-unused-brs-multi-function"
RemoveUnusedBrsResultRefinalizeProfile =>
"remove-unused-brs-result-refinalize"
RemoveUnusedBrsMultivalueDropProfile => "remove-unused-brs-multivalue-drop"
RemoveUnusedBrsWrapperCleanupProfile => "remove-unused-brs-wrapper-cleanup"
RemoveUnusedBrsSelectifyProfile => "remove-unused-brs-selectify"
RemoveUnusedBrsTailFlowProfile => "remove-unused-brs-tail-flow"
RemoveUnusedBrsOneArmIfProfile => "remove-unused-brs-one-arm-if"
RemoveUnusedBrsLoopProfile => "remove-unused-brs-loop"
RemoveUnusedBrsSinkBlocksProfile => "remove-unused-brs-sink-blocks"
RemoveUnusedBrsEhProfile => "remove-unused-brs-eh"
RemoveUnusedBrsJumpThreadProfile => "remove-unused-brs-jump-thread"
RemoveUnusedBrsTablifyProfile => "remove-unused-brs-tablify"
RemoveUnusedBrsOptimizeSetIfProfile => "remove-unused-brs-optimize-set-if"
RemoveUnusedBrsRestructureIfProfile => "remove-unused-brs-restructure-if"
RemoveUnusedBrsAdjacentBranchProfile => "remove-unused-brs-adjacent-branch"
RemoveUnusedBrsWinBoundaryProfile => "remove-unused-brs-win-boundary"
RemoveUnusedBrsAllProfile => "remove-unused-brs-all"
DuplicateImportEliminationFunctionsProfile =>
"duplicate-import-elimination-functions"
DuplicateImportEliminationIdentityProfile =>
"duplicate-import-elimination-identity"
DuplicateImportEliminationModuleCodeProfile =>
"duplicate-import-elimination-module-code"
DuplicateImportEliminationLegacyEhProfile =>
"duplicate-import-elimination-legacy-eh"
DuplicateImportEliminationNonfunctionProfile =>
"duplicate-import-elimination-nonfunction"
DuplicateImportEliminationAllProfile => "duplicate-import-elimination"
LocalCseTriggerProfile => "local-cse"
DuplicateFunctionEliminationTriggerProfile =>
"duplicate-function-elimination"
MergeSimilarFunctionsLiteralsProfile => "merge-similar-functions-literals"
MergeSimilarFunctionsRepeatedDiffProfile =>
"merge-similar-functions-repeated-diff"
MergeSimilarFunctionsExactDuplicatesProfile =>
"merge-similar-functions-exact-duplicates"
MergeSimilarFunctionsDuplicateTypesProfile =>
"merge-similar-functions-duplicate-types"
MergeSimilarFunctionsLocalsProfile => "merge-similar-functions-locals"
MergeSimilarFunctionsNestedProfile => "merge-similar-functions-nested"
MergeSimilarFunctionsCallTargetsProfile =>
"merge-similar-functions-call-targets"
MergeSimilarFunctionsTailCallsProfile =>
"merge-similar-functions-tail-calls"
MergeSimilarFunctionsRecordCopyProfile =>
"merge-similar-functions-record-copy"
MergeSimilarFunctionsAllProfile => "merge-similar-functions-all"
SsaNomergeCoverageProfile => "ssa-nomerge-coverage"
SsaNomergeSmokeProfile => "ssa-nomerge-smoke"
SsaNomergeParityProfile => "ssa-nomerge-parity"
SsaNomergeStressProfile => "ssa-nomerge-stress"
SsaNomergeAllProfile => "ssa-nomerge-all"
SsaFreshSetProfile => "ssa-fresh-set"
SsaFreshTeeProfile => "ssa-fresh-tee"
SsaParamEntryProfile => "ssa-param-entry"
SsaDefaultNumericProfile => "ssa-default-numeric"
SsaDefaultRefProfile => "ssa-default-ref"
SsaUnreachableProfile => "ssa-unreachable"
SsaMergeExplicitProfile => "ssa-merge-explicit"
SsaMergeParamEntryProfile => "ssa-merge-param-entry"
SsaMergeDefaultEntryProfile => "ssa-merge-default-entry"
SsaMergeSharedSetsProfile => "ssa-merge-shared-sets"
SsaLoopProfile => "ssa-loop"
SsaBranchProfile => "ssa-branch"
SsaTypedControlProfile => "ssa-typed-control"
SsaNestedValueProfile => "ssa-nested-value"
SsaEhProfile => "ssa-eh"
SsaAllProfile => "ssa-all"
SimplifyLocalsLocalTrafficProfile => "simplify-locals-local-traffic"
SimplifyLocalsStructureResultProfile => "simplify-locals-structure-result"
SimplifyLocalsFlatParentProfile => "simplify-locals-flat-parent"
SimplifyLocalsEffectOrderProfile => "simplify-locals-effect-order"
SimplifyLocalsStressProfile => "simplify-locals-stress"
SimplifyLocalsFamilyCoverageProfile => "simplify-locals-family-coverage"
SimplifyLocalsAllProfile => "simplify-locals-all"
SimplifyLocalsNoteeAllProfile => "simplify-locals-notee-all"
SimplifyLocalsNoteeNostructureAllProfile =>
"simplify-locals-notee-nostructure-all"
SimplifyLocalsNonestingAllProfile => "simplify-locals-nonesting-all"
SimplifyLocalsNostructureStraightLineProfile =>
"simplify-locals-nostructure-straight-line"
SimplifyLocalsNostructureTeeControlProfile =>
"simplify-locals-nostructure-tee-control"
SimplifyLocalsNostructureEffectOrderProfile =>
"simplify-locals-nostructure-effect-order"
SimplifyLocalsNostructureAllProfile => "simplify-locals-nostructure-all"
ReorderLocalsHotSortProfile => "reorder-locals-hot-sort"
ReorderLocalsPermutationOnlyProfile => "reorder-locals-permutation-only"
ReorderLocalsFirstUseTiesProfile => "reorder-locals-first-use-ties"
ReorderLocalsMixedTypesProfile => "reorder-locals-mixed-types"
ReorderLocalsReferenceTypesProfile => "reorder-locals-reference-types"
ReorderLocalsUnusedTrimProfile => "reorder-locals-unused-trim"
ReorderLocalsStructuredProfile => "reorder-locals-structured"
ReorderLocalsLegacyEhProfile => "reorder-locals-legacy-eh"
ReorderLocalsMultiFunctionProfile => "reorder-locals-multi-function"
ReorderLocalsNameRepairProfile => "reorder-locals-name-repair"
ReorderLocalsAllProfile => "reorder-locals-all"
OptimizeCastsLaterReuseProfile => "optimize-casts-later-reuse"
OptimizeCastsEarlyMotionProfile => "optimize-casts-early-motion"
OptimizeCastsBarriersProfile => "optimize-casts-barriers"
OptimizeCastsBestCastProfile => "optimize-casts-best-cast"
OptimizeCastsRefAsProfile => "optimize-casts-ref-as"
OptimizeCastsStaticFoldsProfile => "optimize-casts-static-folds"
OptimizeCastsNeighborhoodProfile => "optimize-casts-neighborhood"
OptimizeCastsAllProfile => "optimize-casts-all"
PassOiDefaultScalarProfile => "pass-oi-default-scalar"
PassOiLocalFactsProfile => "pass-oi-local-facts"
PassOiBooleanSelectProfile => "pass-oi-boolean-select"
PassOiMemoryBulkProfile => "pass-oi-memory-bulk"
PassOiCallRefProfile => "pass-oi-call-ref"
PassOiRefGcProfile => "pass-oi-ref-gc"
PassOiGcAggregateProfile => "pass-oi-gc-aggregate"
PassOiDescriptorGcProfile => "pass-oi-descriptor-gc"
PassOiTupleProfile => "pass-oi-tuple"
PassOiAllProfile => "pass-oi-all"
FlattenFunctionResultsProfile => "flatten-function-results"
FlattenOperandsProfile => "flatten-operands"
FlattenBlocksProfile => "flatten-blocks"
FlattenIfsProfile => "flatten-ifs"
FlattenLoopsProfile => "flatten-loops"
FlattenTeeProfile => "flatten-tee"
FlattenBrProfile => "flatten-br"
FlattenBrIfProfile => "flatten-br-if"
FlattenBrTableProfile => "flatten-br-table"
FlattenUnreachableProfile => "flatten-unreachable"
FlattenMultivalueProfile => "flatten-multivalue"
FlattenLegacyEhProfile => "flatten-legacy-eh"
FlattenAllProfile => "flatten-all"
DirectizeConstantProfile => "directize-constant"
DirectizeSelectProfile => "directize-select"
DirectizeTableFactsProfile => "directize-table-facts"
DirectizeTailCallProfile => "directize-tail-call"
DirectizeGcProfile => "directize-gc"
DirectizeTable64Profile => "directize-table64"
DirectizeLegacyEhProfile => "directize-legacy-eh"
DirectizeBoundaryProfile => "directize-boundaries"
DirectizeAllProfile => "directize-all"
RandomAllProfilesProfile => "random-all-profiles"
CampaignMemory64MultiMemoryProfile => "campaign-memory64-multimemory"
CampaignEhControlProfile => "campaign-eh-control"
CampaignGcRefSubtypesProfile => "campaign-gc-ref-subtypes"
CampaignSimdNumericProfile => "campaign-simd-numeric"
CampaignCallTopologyProfile => "campaign-call-topology"
CampaignSegmentStateProfile => "campaign-segment-state"
}
}
///|
pub fn gen_valid_profile_is_composite(profile : GenValidProfile) -> Bool {
match profile {
VacuumProfile
| RseAllProfile
| DaeAllProfile
| ConstraintAllProfile
| Dae2AllProfile
| DaeOptimizingProfile
| GsiDescCastAllProfile
| PrecomputeAllProfile
| PickLoadSignsAllProfile
| CodePushingAllProfile
| MergeBlocksAllProfile
| RumeAllProfile
| ReorderGlobalsAllProfile
| GlobalRefiningAllProfile
| CodeFoldingAllProfile
| TupleOptimizationAllProfile
| DeadCodeEliminationAllProfile
| HeapStoreOptimizationProfile
| MemoryPackingAllProfile
| Heap2LocalAllProfile
| LocalSubtypingAllProfile
| CoalesceLocalsAllProfile
| MergeLocalsAllProfile
| RemoveUnusedBrsAllProfile
| DuplicateImportEliminationAllProfile
| MergeSimilarFunctionsAllProfile
| SsaNomergeAllProfile
| SsaAllProfile
| SimplifyLocalsAllProfile
| SimplifyLocalsNoteeAllProfile
| SimplifyLocalsNoteeNostructureAllProfile
| SimplifyLocalsNonestingAllProfile
| SimplifyLocalsNostructureAllProfile
| ReorderLocalsAllProfile
| OptimizeCastsAllProfile
| InliningOptimizingAllProfile
| PassOiAllProfile
| SgoAllProfile
| PggAllProfile
| FlattenAllProfile
| DirectizeAllProfile
| EngineStateAllProfile
| EngineCompileShapesProfile
| EngineProposalMatrixProfile
| EngineStateCoreProfile
| EngineTieringStressProfile
| SemanticOptimizerAllProfile
| RandomAllProfilesProfile => true
_ => false
}
}
///|
pub fn gen_valid_profile_members(
profile : GenValidProfile,
) -> Array[GenValidProfileMember] {
match profile {
VacuumProfile =>
[
GenValidProfileMember::new(VacuumCoreProfile, 2),
GenValidProfileMember::new(VacuumTerminalUnreachableProfile, 1),
GenValidProfileMember::new(VacuumStructuralWrappersProfile, 1),
GenValidProfileMember::new(VacuumDroppedParentEffectsProfile, 1),
GenValidProfileMember::new(VacuumConstantResultIfProfile, 1),
GenValidProfileMember::new(VacuumCallPrefixContinuationProfile, 1),
GenValidProfileMember::new(VacuumLocalsetPrefixPreserveProfile, 1),
GenValidProfileMember::new(VacuumHazardBoundaryProfile, 1),
]
RseAllProfile =>
[
GenValidProfileMember::new(RseCoreSameValueProfile, 3),
GenValidProfileMember::new(RseLocalCopySelfSetProfile, 2),
GenValidProfileMember::new(RseCfgMergeProfile, 3),
GenValidProfileMember::new(RseLoopFlowProfile, 2),
GenValidProfileMember::new(RseRefinedGetProfile, 2),
GenValidProfileMember::new(RseRefinementWrappersProfile, 2),
GenValidProfileMember::new(RseAggregateRefinalizeProfile, 2),
GenValidProfileMember::new(RseExceptionBoundariesProfile, 1),
GenValidProfileMember::new(RseHazardBoundaryProfile, 2),
GenValidProfileMember::new(RseVacuumTailProfile, 2),
]
ConstraintAllProfile =>
[
GenValidProfileMember::new(ConstraintIntegerProfile, 1),
GenValidProfileMember::new(ConstraintJoinsProfile, 1),
GenValidProfileMember::new(ConstraintLoopsProfile, 1),
GenValidProfileMember::new(ConstraintTeesProfile, 1),
GenValidProfileMember::new(ConstraintWraparoundProfile, 1),
GenValidProfileMember::new(ConstraintI64Profile, 1),
GenValidProfileMember::new(ConstraintLogicalProfile, 1),
GenValidProfileMember::new(ConstraintReferencesProfile, 1),
GenValidProfileMember::new(ConstraintUnreachableProfile, 1),
GenValidProfileMember::new(ConstraintRelationsProfile, 1),
GenValidProfileMember::new(ConstraintEffectsProfile, 1),
GenValidProfileMember::new(ConstraintFloatBoundaryProfile, 1),
]
Dae2AllProfile =>
[
GenValidProfileMember::new(Dae2ForwardedResultsProfile, 1),
GenValidProfileMember::new(Dae2CyclesProfile, 1),
GenValidProfileMember::new(Dae2ControlFlowProfile, 1),
GenValidProfileMember::new(Dae2EffectfulArgumentsProfile, 1),
GenValidProfileMember::new(Dae2TupleResultsProfile, 1),
GenValidProfileMember::new(Dae2TailCallsProfile, 1),
GenValidProfileMember::new(Dae2IndirectProfile, 1),
GenValidProfileMember::new(Dae2OpenWorldProfile, 1),
GenValidProfileMember::new(Dae2ReferenceTypesProfile, 1),
GenValidProfileMember::new(Dae2LocalsProfile, 1),
GenValidProfileMember::new(Dae2ContinuationsProfile, 1),
GenValidProfileMember::new(Dae2ExceptionsProfile, 1),
GenValidProfileMember::new(Dae2CallRefProfile, 1),
GenValidProfileMember::new(Dae2IntrinsicsProfile, 1),
]
DaeAllProfile =>
[
GenValidProfileMember::new(DaeUnusedParamsProfile, 3),
GenValidProfileMember::new(DaeEffectfulArgsProfile, 2),
GenValidProfileMember::new(DaeConstantArgsProfile, 3),
GenValidProfileMember::new(DaeUnusedReturnsProfile, 2),
GenValidProfileMember::new(DaeArgTypeRefinementProfile, 1),
GenValidProfileMember::new(DaeReturnTypeRefinementProfile, 1),
GenValidProfileMember::new(DaeUnseenCallBoundaryProfile, 1),
GenValidProfileMember::new(DaeTailCallBoundaryProfile, 1),
GenValidProfileMember::new(DaeLocalizationProfile, 1),
GenValidProfileMember::new(DaeConvergenceProfile, 1),
]
DaeOptimizingProfile =>
[
GenValidProfileMember::new(DaeOptimizingCoreProfile, 3),
GenValidProfileMember::new(DaeOptimizingManyTouchedProfile, 2),
GenValidProfileMember::new(DaeOptimizingMediumModuleProfile, 2),
GenValidProfileMember::new(DaeOptimizingLargeLocalsProfile, 2),
GenValidProfileMember::new(DaeOptimizingTouchedCallerProfile, 2),
GenValidProfileMember::new(DaeOptimizingForwardedSuffixProfile, 2),
GenValidProfileMember::new(DaeOptimizingResultControlProfile, 2),
GenValidProfileMember::new(DaeOptimizingStructuredLocalsProfile, 3),
GenValidProfileMember::new(DaeOptimizingReturnCleanupProfile, 2),
GenValidProfileMember::new(DaeOptimizingImmutableFieldProfile, 3),
GenValidProfileMember::new(DaeOptimizingComputedEffectsProfile, 3),
GenValidProfileMember::new(DaeOptimizingTableEffectsProfile, 2),
GenValidProfileMember::new(DaeOptimizingGcComputedProfile, 3),
GenValidProfileMember::new(DaeOptimizingTailBoundaryProfile, 1),
GenValidProfileMember::new(DaeOptimizingTypeReuseProfile, 1),
]
GsiDescCastAllProfile =>
[
GenValidProfileMember::new(GsiDescCastPositiveProfile, 5),
GenValidProfileMember::new(GsiDescCastStrictSubtypeProfile, 2),
GenValidProfileMember::new(GsiDescCastZeroBoundaryProfile, 1),
GenValidProfileMember::new(GsiDescCastMultiBoundaryProfile, 1),
GenValidProfileMember::new(GsiDescCastUnreachableBoundaryProfile, 1),
]
PrecomputeAllProfile =>
[
GenValidProfileMember::new(PrecomputeScalarProfile, 2),
GenValidProfileMember::new(PrecomputeScalarValueProfile, 3),
GenValidProfileMember::new(PrecomputeGcValueProfile, 2),
GenValidProfileMember::new(PrecomputeEffectfulValueProfile, 2),
GenValidProfileMember::new(PrecomputeControlProfile, 2),
GenValidProfileMember::new(PrecomputeGlobalProfile, 2),
GenValidProfileMember::new(PrecomputeDropCleanupProfile, 2),
GenValidProfileMember::new(PrecomputeEffectBoundaryProfile, 2),
GenValidProfileMember::new(PrecomputeGcAtomicBoundaryProfile, 1),
GenValidProfileMember::new(PrecomputeDirectPrefixWatchProfile, 1),
GenValidProfileMember::new(PrecomputePropagateLocalFactsProfile, 3),
]
PickLoadSignsAllProfile =>
[
GenValidProfileMember::new(PickLoadSignsSignedExtendProfile, 3),
GenValidProfileMember::new(PickLoadSignsSignedShiftProfile, 2),
GenValidProfileMember::new(PickLoadSignsUnsignedMaskProfile, 3),
GenValidProfileMember::new(PickLoadSignsUnsignedShiftProfile, 2),
GenValidProfileMember::new(PickLoadSignsUnknownUseBoundaryProfile, 1),
GenValidProfileMember::new(PickLoadSignsMixedWidthBoundaryProfile, 1),
GenValidProfileMember::new(PickLoadSignsWidthMismatchBoundaryProfile, 1),
GenValidProfileMember::new(PickLoadSignsTeeBoundaryProfile, 1),
GenValidProfileMember::new(PickLoadSignsNoMemoryBoundaryProfile, 1),
GenValidProfileMember::new(PickLoadSignsImportedMemoryProfile, 1),
GenValidProfileMember::new(PickLoadSignsI64WatchProfile, 1),
]
CodePushingAllProfile =>
[
GenValidProfileMember::new(CodePushingIfArmProfile, 1),
GenValidProfileMember::new(CodePushingAfterIfProfile, 1),
GenValidProfileMember::new(CodePushingDroppedIfProfile, 1),
GenValidProfileMember::new(CodePushingBrIfProfile, 1),
GenValidProfileMember::new(CodePushingBrOnNullProfile, 1),
GenValidProfileMember::new(CodePushingBrOnNonNullProfile, 1),
GenValidProfileMember::new(CodePushingBrOnNonNullPrefixProfile, 1),
GenValidProfileMember::new(CodePushingBrOnCastProfile, 1),
GenValidProfileMember::new(CodePushingBrOnCastFailProfile, 1),
GenValidProfileMember::new(CodePushingBrIfValueProfile, 1),
GenValidProfileMember::new(CodePushingMultiSetProfile, 1),
GenValidProfileMember::new(CodePushingMultiSetDroppedIfProfile, 1),
GenValidProfileMember::new(CodePushingMultiSetBrIfProfile, 1),
GenValidProfileMember::new(CodePushingMultiSetLocalCopyProfile, 1),
GenValidProfileMember::new(CodePushingMultiSetNopWindowProfile, 1),
GenValidProfileMember::new(CodePushingLoopBrIfProfile, 1),
GenValidProfileMember::new(CodePushingMultiSetDropWindowProfile, 1),
GenValidProfileMember::new(CodePushingMultiSetLocalGetWindowProfile, 1),
GenValidProfileMember::new(CodePushingMultiSetGlobalGetWindowProfile, 1),
GenValidProfileMember::new(CodePushingZeroReadProfile, 1),
]
MergeBlocksAllProfile =>
[
GenValidProfileMember::new(MergeBlocksStructuralProfile, 3),
GenValidProfileMember::new(MergeBlocksExpressionProfile, 3),
GenValidProfileMember::new(MergeBlocksEffectProfile, 2),
GenValidProfileMember::new(MergeBlocksEhAtomicProfile, 2),
]
RumeAllProfile =>
[
GenValidProfileMember::new(RumeDeadGraphProfile, 3),
GenValidProfileMember::new(RumeTableTrapProfile, 2),
GenValidProfileMember::new(RumeLegacyEhProfile, 2),
GenValidProfileMember::new(RumeSpecialImportsProfile, 3),
GenValidProfileMember::new(RumeCallableReferencesProfile, 2),
GenValidProfileMember::new(RumeContinuationsDescriptorsProfile, 2),
GenValidProfileMember::new(RumeIndexRemapStressProfile, 3),
]
GlobalRefiningAllProfile =>
[
GenValidProfileMember::new(GlobalRefiningPrivateWritesProfile, 1),
GenValidProfileMember::new(GlobalRefiningExportBoundariesProfile, 1),
GenValidProfileMember::new(GlobalRefiningImportAliasesProfile, 1),
GenValidProfileMember::new(GlobalRefiningSubtypeJoinsProfile, 1),
]
ReorderGlobalsAllProfile =>
[
GenValidProfileMember::new(ReorderGlobalsHotTrafficProfile, 3),
GenValidProfileMember::new(ReorderGlobalsDependencySearchProfile, 3),
GenValidProfileMember::new(ReorderGlobalsImportedProfile, 2),
GenValidProfileMember::new(ReorderGlobalsModuleCodeProfile, 3),
GenValidProfileMember::new(ReorderGlobalsLegacyEhProfile, 3),
GenValidProfileMember::new(ReorderGlobalsMetadataRemapProfile, 2),
GenValidProfileMember::new(ReorderGlobalsThresholdProfile, 1),
]
CodeFoldingAllProfile =>
[
GenValidProfileMember::new(CodeFoldingIfArmsProfile, 1),
GenValidProfileMember::new(CodeFoldingBlockExitsProfile, 1),
GenValidProfileMember::new(CodeFoldingReturnsProfile, 1),
GenValidProfileMember::new(CodeFoldingTailCallsProfile, 1),
GenValidProfileMember::new(CodeFoldingMovementProfile, 1),
GenValidProfileMember::new(CodeFoldingEhProfile, 1),
]
TupleOptimizationAllProfile =>
[
GenValidProfileMember::new(TupleOptimizationSpillProfile, 3),
GenValidProfileMember::new(TupleOptimizationCopyChainProfile, 2),
GenValidProfileMember::new(TupleOptimizationTeeProfile, 1),
GenValidProfileMember::new(TupleOptimizationAliasCapturesProfile, 3),
]
DeadCodeEliminationAllProfile =>
[
GenValidProfileMember::new(DeadCodeEliminationNonControlProfile, 1),
GenValidProfileMember::new(DeadCodeEliminationBlockSuffixProfile, 1),
GenValidProfileMember::new(DeadCodeEliminationIfBothArmsProfile, 1),
GenValidProfileMember::new(DeadCodeEliminationIfConditionProfile, 1),
GenValidProfileMember::new(DeadCodeEliminationLoopBodyProfile, 1),
GenValidProfileMember::new(DeadCodeEliminationTryTableProfile, 1),
GenValidProfileMember::new(
DeadCodeEliminationTryTableCatchRefProfile,
1,
),
GenValidProfileMember::new(
DeadCodeEliminationBranchPayloadForwarderProfile,
1,
),
GenValidProfileMember::new(
DeadCodeEliminationPrefixBranchPayloadProfile,
1,
),
GenValidProfileMember::new(
DeadCodeEliminationSplitLocalSetWrapperProfile,
1,
),
GenValidProfileMember::new(
DeadCodeEliminationStructuredPrefixProfile,
1,
),
GenValidProfileMember::new(
DeadCodeEliminationEffectfulStructuredPrefixProfile,
1,
),
]
HeapStoreOptimizationProfile =>
[
GenValidProfileMember::new(HsoTeeProfile, 1),
GenValidProfileMember::new(HsoChainProfile, 1),
GenValidProfileMember::new(HsoDefaultProfile, 1),
GenValidProfileMember::new(HsoSideEffectsProfile, 1),
GenValidProfileMember::new(HsoDescriptorProfile, 1),
GenValidProfileMember::new(HsoControlFlowProfile, 1),
GenValidProfileMember::new(HsoSwapProfile, 1),
GenValidProfileMember::new(HsoSharedOrderingProfile, 1),
GenValidProfileMember::new(HsoBoundariesProfile, 1),
]
MemoryPackingAllProfile =>
[
GenValidProfileMember::new(MemoryPackingActiveRangesProfile, 3),
GenValidProfileMember::new(MemoryPackingActiveTrapsProfile, 2),
GenValidProfileMember::new(MemoryPackingDefinedOverlapProfile, 2),
GenValidProfileMember::new(MemoryPackingPassiveSplitsProfile, 3),
GenValidProfileMember::new(MemoryPackingSegmentOpsProfile, 2),
GenValidProfileMember::new(MemoryPackingMemory64Profile, 2),
GenValidProfileMember::new(MemoryPackingBoundariesProfile, 1),
]
Heap2LocalAllProfile =>
[
GenValidProfileMember::new(Heap2LocalStructProfile, 3),
GenValidProfileMember::new(Heap2LocalArrayProfile, 2),
GenValidProfileMember::new(Heap2LocalRefProfile, 2),
GenValidProfileMember::new(Heap2LocalOwnerUpdatesProfile, 3),
]
LocalSubtypingAllProfile =>
[
GenValidProfileMember::new(LocalSubtypingStraightLineProfile, 2),
GenValidProfileMember::new(LocalSubtypingStructuredProfile, 2),
GenValidProfileMember::new(LocalSubtypingUnreachableTailProfile, 1),
GenValidProfileMember::new(LocalSubtypingLubsProfile, 2),
GenValidProfileMember::new(LocalSubtypingIterationProfile, 2),
GenValidProfileMember::new(LocalSubtypingNullBottomProfile, 1),
GenValidProfileMember::new(LocalSubtypingControlRefinalizeProfile, 1),
]
CoalesceLocalsAllProfile =>
[
GenValidProfileMember::new(CoalesceLocalsStraightLineProfile, 3),
GenValidProfileMember::new(CoalesceLocalsStructuredProfile, 2),
GenValidProfileMember::new(CoalesceLocalsLoopCopyThroughProfile, 2),
GenValidProfileMember::new(CoalesceLocalsEntryValuesProfile, 1),
GenValidProfileMember::new(CoalesceLocalsCopyPreferenceProfile, 2),
GenValidProfileMember::new(CoalesceLocalsTeeCopiesProfile, 1),
GenValidProfileMember::new(CoalesceLocalsInterBlockProfile, 1),
GenValidProfileMember::new(CoalesceLocalsUnreachableProfile, 1),
GenValidProfileMember::new(CoalesceLocalsLegacyEhProfile, 1),
GenValidProfileMember::new(CoalesceLocalsLargeUnusedProfile, 1),
GenValidProfileMember::new(CoalesceLocalsExactTypesProfile, 1),
]
MergeLocalsAllProfile =>
[
GenValidProfileMember::new(MergeLocalsForwardProfile, 1),
GenValidProfileMember::new(MergeLocalsForwardMultipleProfile, 1),
GenValidProfileMember::new(MergeLocalsPartialInfluenceProfile, 1),
GenValidProfileMember::new(MergeLocalsReverseProfile, 1),
GenValidProfileMember::new(MergeLocalsReverseBoundaryProfile, 1),
GenValidProfileMember::new(MergeLocalsControlProfile, 1),
GenValidProfileMember::new(MergeLocalsTeeProfile, 1),
GenValidProfileMember::new(MergeLocalsMergeBoundaryProfile, 1),
GenValidProfileMember::new(MergeLocalsTypeBoundaryProfile, 1),
GenValidProfileMember::new(MergeLocalsRollbackProfile, 1),
GenValidProfileMember::new(MergeLocalsReverseRollbackProfile, 1),
GenValidProfileMember::new(MergeLocalsNestedCopiesProfile, 1),
GenValidProfileMember::new(MergeLocalsTrivialConfusionProfile, 1),
GenValidProfileMember::new(MergeLocalsUnreachableProfile, 1),
GenValidProfileMember::new(MergeLocalsLegacyEhProfile, 1),
]
RemoveUnusedBrsAllProfile =>
[
GenValidProfileMember::new(RemoveUnusedBrsConstantBrIfProfile, 2),
GenValidProfileMember::new(RemoveUnusedBrsSingleTargetBrTableProfile, 2),
GenValidProfileMember::new(RemoveUnusedBrsMultiFunctionProfile, 2),
GenValidProfileMember::new(RemoveUnusedBrsResultRefinalizeProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsMultivalueDropProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsWrapperCleanupProfile, 2),
GenValidProfileMember::new(RemoveUnusedBrsSelectifyProfile, 2),
GenValidProfileMember::new(RemoveUnusedBrsTailFlowProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsOneArmIfProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsLoopProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsSinkBlocksProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsEhProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsJumpThreadProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsTablifyProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsOptimizeSetIfProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsRestructureIfProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsAdjacentBranchProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsControlProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsSwitchProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsCleanupProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsGcProfile, 1),
]
DuplicateImportEliminationAllProfile =>
[
GenValidProfileMember::new(
DuplicateImportEliminationFunctionsProfile,
2,
),
GenValidProfileMember::new(DuplicateImportEliminationIdentityProfile, 2),
GenValidProfileMember::new(
DuplicateImportEliminationModuleCodeProfile,
2,
),
GenValidProfileMember::new(DuplicateImportEliminationLegacyEhProfile, 4),
GenValidProfileMember::new(
DuplicateImportEliminationNonfunctionProfile,
2,
),
]
MergeSimilarFunctionsAllProfile =>
[
GenValidProfileMember::new(MergeSimilarFunctionsLiteralsProfile, 3),
GenValidProfileMember::new(MergeSimilarFunctionsRepeatedDiffProfile, 2),
GenValidProfileMember::new(
MergeSimilarFunctionsExactDuplicatesProfile,
2,
),
GenValidProfileMember::new(
MergeSimilarFunctionsDuplicateTypesProfile,
2,
),
GenValidProfileMember::new(MergeSimilarFunctionsLocalsProfile, 2),
GenValidProfileMember::new(MergeSimilarFunctionsNestedProfile, 2),
GenValidProfileMember::new(MergeSimilarFunctionsCallTargetsProfile, 3),
GenValidProfileMember::new(MergeSimilarFunctionsTailCallsProfile, 2),
]
SsaNomergeAllProfile =>
[
GenValidProfileMember::new(SsaNomergeParityProfile, 3),
GenValidProfileMember::new(SsaNomergeSmokeProfile, 2),
GenValidProfileMember::new(SsaNomergeCoverageProfile, 2),
GenValidProfileMember::new(SsaNomergeStressProfile, 1),
]
SsaAllProfile =>
[
GenValidProfileMember::new(SsaFreshSetProfile, 1),
GenValidProfileMember::new(SsaFreshTeeProfile, 1),
GenValidProfileMember::new(SsaParamEntryProfile, 1),
GenValidProfileMember::new(SsaDefaultNumericProfile, 1),
GenValidProfileMember::new(SsaDefaultRefProfile, 1),
GenValidProfileMember::new(SsaUnreachableProfile, 1),
GenValidProfileMember::new(SsaMergeExplicitProfile, 1),
GenValidProfileMember::new(SsaMergeParamEntryProfile, 1),
GenValidProfileMember::new(SsaMergeDefaultEntryProfile, 1),
GenValidProfileMember::new(SsaMergeSharedSetsProfile, 1),
GenValidProfileMember::new(SsaLoopProfile, 1),
GenValidProfileMember::new(SsaBranchProfile, 1),
GenValidProfileMember::new(SsaTypedControlProfile, 1),
GenValidProfileMember::new(SsaNestedValueProfile, 1),
GenValidProfileMember::new(SsaEhProfile, 1),
]
SimplifyLocalsAllProfile =>
[
GenValidProfileMember::new(SimplifyLocalsLocalTrafficProfile, 3),
GenValidProfileMember::new(SimplifyLocalsStructureResultProfile, 3),
GenValidProfileMember::new(SimplifyLocalsFlatParentProfile, 2),
GenValidProfileMember::new(SimplifyLocalsEffectOrderProfile, 2),
GenValidProfileMember::new(SimplifyLocalsStressProfile, 1),
GenValidProfileMember::new(SimplifyLocalsFamilyCoverageProfile, 5),
GenValidProfileMember::new(Dae2LocalsProfile, 1),
]
SimplifyLocalsNoteeAllProfile =>
[
GenValidProfileMember::new(SimplifyLocalsLocalTrafficProfile, 3),
GenValidProfileMember::new(SimplifyLocalsStructureResultProfile, 3),
GenValidProfileMember::new(SimplifyLocalsFlatParentProfile, 2),
GenValidProfileMember::new(SimplifyLocalsEffectOrderProfile, 2),
GenValidProfileMember::new(SimplifyLocalsStressProfile, 1),
GenValidProfileMember::new(SimplifyLocalsFamilyCoverageProfile, 5),
]
SimplifyLocalsNoteeNostructureAllProfile =>
[
GenValidProfileMember::new(SimplifyLocalsLocalTrafficProfile, 3),
GenValidProfileMember::new(SimplifyLocalsStructureResultProfile, 2),
GenValidProfileMember::new(SimplifyLocalsFlatParentProfile, 3),
GenValidProfileMember::new(SimplifyLocalsEffectOrderProfile, 2),
GenValidProfileMember::new(SimplifyLocalsStressProfile, 1),
GenValidProfileMember::new(SimplifyLocalsFamilyCoverageProfile, 5),
]
SimplifyLocalsNonestingAllProfile =>
[
GenValidProfileMember::new(SimplifyLocalsLocalTrafficProfile, 4),
GenValidProfileMember::new(SimplifyLocalsStructureResultProfile, 2),
GenValidProfileMember::new(SimplifyLocalsFlatParentProfile, 4),
GenValidProfileMember::new(SimplifyLocalsEffectOrderProfile, 2),
GenValidProfileMember::new(SimplifyLocalsStressProfile, 1),
GenValidProfileMember::new(SimplifyLocalsFamilyCoverageProfile, 5),
]
SimplifyLocalsNostructureAllProfile =>
[
GenValidProfileMember::new(
SimplifyLocalsNostructureStraightLineProfile,
3,
),
GenValidProfileMember::new(
SimplifyLocalsNostructureTeeControlProfile,
2,
),
GenValidProfileMember::new(
SimplifyLocalsNostructureEffectOrderProfile,
2,
),
GenValidProfileMember::new(SimplifyLocalsFamilyCoverageProfile, 5),
]
ReorderLocalsAllProfile =>
[
GenValidProfileMember::new(ReorderLocalsHotSortProfile, 3),
GenValidProfileMember::new(ReorderLocalsPermutationOnlyProfile, 2),
GenValidProfileMember::new(ReorderLocalsFirstUseTiesProfile, 2),
GenValidProfileMember::new(ReorderLocalsMixedTypesProfile, 2),
GenValidProfileMember::new(ReorderLocalsReferenceTypesProfile, 2),
GenValidProfileMember::new(ReorderLocalsUnusedTrimProfile, 2),
GenValidProfileMember::new(ReorderLocalsStructuredProfile, 2),
GenValidProfileMember::new(ReorderLocalsLegacyEhProfile, 2),
GenValidProfileMember::new(ReorderLocalsMultiFunctionProfile, 2),
GenValidProfileMember::new(ReorderLocalsNameRepairProfile, 1),
]
OptimizeCastsAllProfile =>
[
GenValidProfileMember::new(OptimizeCastsLaterReuseProfile, 3),
GenValidProfileMember::new(OptimizeCastsEarlyMotionProfile, 2),
GenValidProfileMember::new(OptimizeCastsBarriersProfile, 2),
GenValidProfileMember::new(OptimizeCastsBestCastProfile, 2),
GenValidProfileMember::new(OptimizeCastsRefAsProfile, 2),
GenValidProfileMember::new(OptimizeCastsStaticFoldsProfile, 1),
GenValidProfileMember::new(OptimizeCastsNeighborhoodProfile, 1),
]
InliningOptimizingAllProfile =>
[
GenValidProfileMember::new(InliningOptimizingDirectWrapperProfile, 3),
GenValidProfileMember::new(InliningOptimizingParamSpillProfile, 3),
GenValidProfileMember::new(InliningOptimizingReturnCallProfile, 2),
GenValidProfileMember::new(InliningOptimizingCleanupPayoffProfile, 2),
]
PassOiAllProfile =>
[
GenValidProfileMember::new(PassOiDefaultScalarProfile, 1),
GenValidProfileMember::new(PassOiLocalFactsProfile, 1),
GenValidProfileMember::new(PassOiBooleanSelectProfile, 1),
GenValidProfileMember::new(PassOiMemoryBulkProfile, 1),
GenValidProfileMember::new(PassOiCallRefProfile, 1),
GenValidProfileMember::new(PassOiRefGcProfile, 1),
GenValidProfileMember::new(PassOiGcAggregateProfile, 1),
GenValidProfileMember::new(PassOiDescriptorGcProfile, 1),
GenValidProfileMember::new(PassOiTupleProfile, 1),
]
SgoAllProfile =>
[
GenValidProfileMember::new(SgoInitializerFoldingProfile, 2),
GenValidProfileMember::new(SgoSameInitDeadSetProfile, 2),
GenValidProfileMember::new(SgoReadOnlyToWriteProfile, 3),
GenValidProfileMember::new(SgoStartupPropagationProfile, 2),
GenValidProfileMember::new(SgoRuntimePropagationProfile, 3),
GenValidProfileMember::new(SgoNestedCleanupProfile, 2),
]
PggAllProfile =>
[
GenValidProfileMember::new(PggDirectGlobalProfile, 1),
GenValidProfileMember::new(PggCompoundGlobalProfile, 1),
GenValidProfileMember::new(PggGcCompoundProfile, 1),
GenValidProfileMember::new(PggDataOffsetProfile, 1),
GenValidProfileMember::new(PggElemOffsetProfile, 1),
]
FlattenAllProfile =>
[
GenValidProfileMember::new(FlattenFunctionResultsProfile, 1),
GenValidProfileMember::new(FlattenOperandsProfile, 1),
GenValidProfileMember::new(FlattenBlocksProfile, 1),
GenValidProfileMember::new(FlattenIfsProfile, 1),
GenValidProfileMember::new(FlattenLoopsProfile, 1),
GenValidProfileMember::new(FlattenTeeProfile, 1),
GenValidProfileMember::new(FlattenBrProfile, 1),
GenValidProfileMember::new(FlattenBrIfProfile, 1),
GenValidProfileMember::new(FlattenBrTableProfile, 1),
GenValidProfileMember::new(FlattenUnreachableProfile, 1),
GenValidProfileMember::new(FlattenMultivalueProfile, 1),
GenValidProfileMember::new(FlattenLegacyEhProfile, 1),
]
DirectizeAllProfile =>
[
GenValidProfileMember::new(DirectizeConstantProfile, 3),
GenValidProfileMember::new(DirectizeSelectProfile, 3),
GenValidProfileMember::new(DirectizeTableFactsProfile, 3),
GenValidProfileMember::new(DirectizeTailCallProfile, 2),
GenValidProfileMember::new(DirectizeGcProfile, 2),
GenValidProfileMember::new(DirectizeTable64Profile, 2),
GenValidProfileMember::new(DirectizeLegacyEhProfile, 3),
GenValidProfileMember::new(DirectizeBoundaryProfile, 2),
]
EngineStateAllProfile =>
[
GenValidProfileMember::new(EngineStateScalarControlProfile, 3),
GenValidProfileMember::new(EngineStateCallsProfile, 2),
GenValidProfileMember::new(EngineStateMemoryProfile, 2),
GenValidProfileMember::new(EngineStateTableProfile, 1),
GenValidProfileMember::new(EngineStateSimdProfile, 1),
GenValidProfileMember::new(EngineStateImportsProfile, 2),
GenValidProfileMember::new(EngineStateInitializationProfile, 1),
GenValidProfileMember::new(EngineStateTrapProfile, 2),
GenValidProfileMember::new(EngineStateMixedProfile, 2),
GenValidProfileMember::new(EngineStateTopologyProfile, 4),
GenValidProfileMember::new(EngineStateEffectsProfile, 4),
GenValidProfileMember::new(EngineStateResourcesProfile, 4),
GenValidProfileMember::new(EngineStateBoundariesProfile, 3),
GenValidProfileMember::new(EngineStateOptimizerShapesProfile, 3),
GenValidProfileMember::new(EngineStateEquivalentFamiliesProfile, 6),
GenValidProfileMember::new(EngineStatePassiveSegmentsProfile, 4),
GenValidProfileMember::new(EngineStateInstantiationBoundariesProfile, 3),
GenValidProfileMember::new(EngineStateMultiResourceProfile, 4),
GenValidProfileMember::new(EngineStateStackPressureProfile, 4),
GenValidProfileMember::new(EngineStateMemoryAliasingProfile, 4),
GenValidProfileMember::new(EngineStateIndirectTrapsProfile, 3),
GenValidProfileMember::new(EngineStateTrapPlacementProfile, 3),
GenValidProfileMember::new(EngineStateCrossInstanceProfile, 3),
GenValidProfileMember::new(EngineStateResourceExhaustionProfile, 3),
GenValidProfileMember::new(EngineStateDecoderTopologyProfile, 4),
GenValidProfileMember::new(EngineStateTailCallsProfile, 1),
GenValidProfileMember::new(EngineStateTypedFunctionReferencesProfile, 1),
GenValidProfileMember::new(EngineStateMemory64Profile, 1),
GenValidProfileMember::new(EngineStateExceptionsProfile, 1),
GenValidProfileMember::new(EngineStateGcProfile, 1),
GenValidProfileMember::new(EngineStateLinkGraphProfile, 3),
GenValidProfileMember::new(EngineStateGcGraphProfile, 4),
GenValidProfileMember::new(EngineStateInitializationGraphProfile, 4),
GenValidProfileMember::new(EngineStateExceptionUnwindProfile, 4),
GenValidProfileMember::new(EngineStateTypeCallMatrixProfile, 4),
GenValidProfileMember::new(EngineStateLebIndexBoundariesProfile, 2),
GenValidProfileMember::new(EngineStateTableReferenceMatrixProfile, 4),
GenValidProfileMember::new(EngineStateMemory64MultiMemoryProfile, 3),
GenValidProfileMember::new(EngineStateTrapCommitMatrixProfile, 4),
GenValidProfileMember::new(EngineStateMetamorphicTwinsProfile, 4),
GenValidProfileMember::new(EngineStateCompilerBoundariesProfile, 4),
GenValidProfileMember::new(EngineStateNanProfile, 4),
GenValidProfileMember::new(EngineStateInvalidModuleProfile, 4),
GenValidProfileMember::new(EngineStateRecursiveMultivalueProfile, 4),
GenValidProfileMember::new(EngineStateSubtypeCastGraphProfile, 4),
]
EngineCompileShapesProfile =>
[
GenValidProfileMember::new(FlattenBlocksProfile, 1),
GenValidProfileMember::new(FlattenIfsProfile, 1),
GenValidProfileMember::new(FlattenLoopsProfile, 1),
GenValidProfileMember::new(FlattenBrTableProfile, 1),
GenValidProfileMember::new(FlattenMultivalueProfile, 1),
GenValidProfileMember::new(MergeBlocksStructuralProfile, 1),
GenValidProfileMember::new(MergeBlocksExpressionProfile, 1),
GenValidProfileMember::new(MergeBlocksEffectProfile, 1),
GenValidProfileMember::new(Dae2ForwardedResultsProfile, 1),
GenValidProfileMember::new(Dae2CyclesProfile, 1),
GenValidProfileMember::new(Dae2ControlFlowProfile, 1),
GenValidProfileMember::new(Dae2TupleResultsProfile, 1),
GenValidProfileMember::new(Dae2IndirectProfile, 1),
GenValidProfileMember::new(Dae2LocalsProfile, 1),
GenValidProfileMember::new(InliningOptimizingDirectWrapperProfile, 1),
GenValidProfileMember::new(InliningOptimizingParamSpillProfile, 1),
GenValidProfileMember::new(InliningOptimizingCleanupPayoffProfile, 1),
GenValidProfileMember::new(SsaFreshSetProfile, 1),
GenValidProfileMember::new(SsaFreshTeeProfile, 1),
GenValidProfileMember::new(SsaMergeExplicitProfile, 1),
GenValidProfileMember::new(SsaLoopProfile, 1),
GenValidProfileMember::new(SsaBranchProfile, 1),
GenValidProfileMember::new(SsaTypedControlProfile, 1),
GenValidProfileMember::new(SsaNestedValueProfile, 1),
GenValidProfileMember::new(CoalesceLocalsStraightLineProfile, 1),
GenValidProfileMember::new(CoalesceLocalsStructuredProfile, 1),
GenValidProfileMember::new(CoalesceLocalsLoopCopyThroughProfile, 1),
GenValidProfileMember::new(CoalesceLocalsInterBlockProfile, 1),
GenValidProfileMember::new(CoalesceLocalsExactTypesProfile, 1),
GenValidProfileMember::new(MergeLocalsForwardProfile, 1),
GenValidProfileMember::new(MergeLocalsReverseProfile, 1),
GenValidProfileMember::new(MergeLocalsControlProfile, 1),
GenValidProfileMember::new(MergeLocalsTeeProfile, 1),
GenValidProfileMember::new(MergeLocalsNestedCopiesProfile, 1),
GenValidProfileMember::new(MemoryPackingActiveRangesProfile, 1),
GenValidProfileMember::new(MemoryPackingDefinedOverlapProfile, 1),
GenValidProfileMember::new(MemoryPackingPassiveSplitsProfile, 1),
GenValidProfileMember::new(MemoryPackingSegmentOpsProfile, 1),
GenValidProfileMember::new(MemoryPackingBoundariesProfile, 1),
GenValidProfileMember::new(ReorderGlobalsHotTrafficProfile, 1),
GenValidProfileMember::new(ReorderGlobalsDependencySearchProfile, 1),
GenValidProfileMember::new(ReorderGlobalsModuleCodeProfile, 1),
GenValidProfileMember::new(ReorderGlobalsMetadataRemapProfile, 1),
GenValidProfileMember::new(ReorderGlobalsThresholdProfile, 1),
GenValidProfileMember::new(CampaignSegmentStateProfile, 1),
GenValidProfileMember::new(EngineStateDecoderTopologyProfile, 1),
GenValidProfileMember::new(EngineStateLebIndexBoundariesProfile, 1),
GenValidProfileMember::new(EngineStateCompilerBoundariesProfile, 1),
]
EngineProposalMatrixProfile =>
[
GenValidProfileMember::new(CampaignSimdNumericProfile, 1),
GenValidProfileMember::new(CampaignGcRefSubtypesProfile, 1),
GenValidProfileMember::new(CampaignEhControlProfile, 1),
GenValidProfileMember::new(CampaignMemory64MultiMemoryProfile, 1),
GenValidProfileMember::new(CampaignCallTopologyProfile, 1),
GenValidProfileMember::new(EngineStateTailCallsProfile, 1),
GenValidProfileMember::new(EngineStateTypedFunctionReferencesProfile, 1),
GenValidProfileMember::new(EngineStateMemory64Profile, 1),
GenValidProfileMember::new(EngineStateExceptionsProfile, 1),
GenValidProfileMember::new(EngineStateGcProfile, 1),
GenValidProfileMember::new(EngineStateTypeCallMatrixProfile, 2),
GenValidProfileMember::new(EngineStateExceptionUnwindProfile, 2),
GenValidProfileMember::new(EngineStateGcGraphProfile, 2),
GenValidProfileMember::new(EngineStateTableReferenceMatrixProfile, 2),
GenValidProfileMember::new(EngineStateMemory64MultiMemoryProfile, 2),
GenValidProfileMember::new(EngineStateRecursiveMultivalueProfile, 2),
GenValidProfileMember::new(EngineStateSubtypeCastGraphProfile, 2),
]
EngineStateCoreProfile =>
[
GenValidProfileMember::new(EngineStateScalarControlProfile, 3),
GenValidProfileMember::new(EngineStateCallsProfile, 2),
GenValidProfileMember::new(EngineStateMemoryProfile, 2),
GenValidProfileMember::new(EngineStateTableProfile, 1),
GenValidProfileMember::new(EngineStateImportsProfile, 2),
GenValidProfileMember::new(EngineStateInitializationProfile, 1),
GenValidProfileMember::new(EngineStateTopologyProfile, 4),
GenValidProfileMember::new(EngineStateEffectsProfile, 4),
GenValidProfileMember::new(EngineStateResourcesProfile, 4),
GenValidProfileMember::new(EngineStateBoundariesProfile, 3),
GenValidProfileMember::new(EngineStateOptimizerShapesProfile, 3),
GenValidProfileMember::new(EngineStateEquivalentFamiliesProfile, 6),
GenValidProfileMember::new(EngineStatePassiveSegmentsProfile, 4),
GenValidProfileMember::new(EngineStateStackPressureProfile, 4),
GenValidProfileMember::new(EngineStateMemoryAliasingProfile, 4),
GenValidProfileMember::new(EngineStateResourceExhaustionProfile, 3),
GenValidProfileMember::new(EngineStateDecoderTopologyProfile, 4),
GenValidProfileMember::new(EngineStateLebIndexBoundariesProfile, 2),
GenValidProfileMember::new(EngineStateCompilerBoundariesProfile, 4),
GenValidProfileMember::new(EngineStateNanProfile, 4),
]
EngineTieringStressProfile =>
[
GenValidProfileMember::new(EngineTieringLoopProfile, 4),
GenValidProfileMember::new(EngineTieringLargeFunctionProfile, 2),
GenValidProfileMember::new(EngineTieringCallChainProfile, 2),
GenValidProfileMember::new(EngineTieringCallFanoutProfile, 2),
GenValidProfileMember::new(EngineTieringIndirectProfile, 3),
GenValidProfileMember::new(EngineTieringLocalsStackProfile, 2),
GenValidProfileMember::new(EngineTieringMemoryProfile, 3),
GenValidProfileMember::new(EngineTieringGcProfile, 1),
]
SemanticOptimizerAllProfile =>
[
GenValidProfileMember::new(SemanticEffectsProfile, 3),
GenValidProfileMember::new(SemanticImportEventsProfile, 3),
GenValidProfileMember::new(SemanticTrapFrontierProfile, 3),
GenValidProfileMember::new(SemanticResourcesProfile, 3),
]
RandomAllProfilesProfile =>
[
GenValidProfileMember::new(GlobalRefiningAllProfile, 1),
GenValidProfileMember::new(CoverageForcedPortableProfile, 1),
GenValidProfileMember::new(BinaryenOraclePortableProfile, 1),
GenValidProfileMember::new(PassFuzzStressProfile, 1),
GenValidProfileMember::new(MergeBlocksAllProfile, 1),
GenValidProfileMember::new(MemoryPackingAllProfile, 1),
GenValidProfileMember::new(PrecomputeAllProfile, 1),
GenValidProfileMember::new(DaeAllProfile, 1),
GenValidProfileMember::new(ConstraintAllProfile, 1),
GenValidProfileMember::new(Dae2AllProfile, 1),
GenValidProfileMember::new(DaeOptimizingProfile, 1),
GenValidProfileMember::new(Heap2LocalAllProfile, 1),
GenValidProfileMember::new(LocalSubtypingAllProfile, 1),
GenValidProfileMember::new(CoalesceLocalsAllProfile, 1),
GenValidProfileMember::new(MergeLocalsAllProfile, 1),
GenValidProfileMember::new(RemoveUnusedBrsAllProfile, 1),
GenValidProfileMember::new(DuplicateImportEliminationAllProfile, 1),
GenValidProfileMember::new(LocalCseTriggerProfile, 1),
GenValidProfileMember::new(
DuplicateFunctionEliminationTriggerProfile,
1,
),
GenValidProfileMember::new(MergeSimilarFunctionsAllProfile, 1),
GenValidProfileMember::new(DirectizeAllProfile, 1),
GenValidProfileMember::new(SsaNomergeSmokeProfile, 1),
GenValidProfileMember::new(SsaNomergeParityProfile, 1),
GenValidProfileMember::new(SsaMergeExplicitProfile, 1),
GenValidProfileMember::new(SsaNestedValueProfile, 1),
GenValidProfileMember::new(PggAllProfile, 1),
GenValidProfileMember::new(CampaignMemory64MultiMemoryProfile, 1),
GenValidProfileMember::new(CampaignEhControlProfile, 1),
GenValidProfileMember::new(CampaignGcRefSubtypesProfile, 1),
GenValidProfileMember::new(CampaignSimdNumericProfile, 1),
GenValidProfileMember::new(CampaignCallTopologyProfile, 1),
GenValidProfileMember::new(CampaignSegmentStateProfile, 1),
]
_ => []
}
}
///|
fn gen_valid_profile_case_roll(seed : UInt64, case_index : Int32) -> UInt64 {
let normalized_index = if case_index <= 0 { 1 } else { case_index }
gen_valid_derive_stream_seed(seed, HarnessShufflingStream) ^
(normalized_index.to_uint64() * 0x9e3779b97f4a7c15UL) ^
0xbf58476d1ce4e5b9UL
}
///|
pub fn gen_valid_case_seed(seed : UInt64, case_index : Int32) -> UInt64 {
gen_valid_derive_stream_seed(seed, HarnessShufflingStream) ^
(case_index.to_uint64() * 0x9e3779b97f4a7c15UL)
}
///|
fn gen_valid_profile_uses_exact_weighted_cycle(
profile : GenValidProfile,
) -> Bool {
profile == EngineStateAllProfile ||
profile == EngineCompileShapesProfile ||
profile == EngineProposalMatrixProfile ||
profile == EngineStateCoreProfile ||
profile == EngineTieringStressProfile
}
///|
pub fn gen_valid_profile_leaf_for_case(
profile : GenValidProfile,
seed : UInt64,
case_index : Int32,
) -> GenValidProfile {
let members = gen_valid_profile_members(profile)
if gen_valid_profile_uses_exact_weighted_cycle(profile) && !members.is_empty() {
let normalized_index = if case_index <= 0 { 1 } else { case_index }
let mut total_weight = 0
for entry in members {
if entry.weight > 0 {
total_weight += entry.weight
}
}
let rotation = (gen_valid_profile_case_roll(seed, 1) %
total_weight.to_uint64()).to_int()
let mut position = (normalized_index - 1 + rotation) % total_weight
for entry in members {
if position < entry.weight {
return entry.profile
}
position -= entry.weight
}
}
if members.is_empty() {
return profile
}
let mut total_weight = 0
for entry in members {
if entry.weight > 0 {
total_weight += entry.weight
}
}
if total_weight <= 0 {
return profile
}
let selector = gen_valid_profile_case_roll(seed, case_index)
// These aggregates use seed bits inside each leaf to choose important
// semantic variants. Avalanche the independent selector so selecting a leaf
// cannot fix those same bits (for example, selecting only odd campaign
// variants). Keep singleton case seeds replayable; only leaf scheduling is
// mixed here.
let selector = if profile == ConstraintAllProfile ||
profile == Dae2AllProfile ||
profile == RandomAllProfilesProfile {
@splitmix.new(seed=selector).next_uint64()
} else {
selector
}
let mut roll = (selector % total_weight.to_uint64()).to_int()
for entry in members {
if entry.weight > 0 {
if roll < entry.weight {
return gen_valid_profile_leaf_for_case(entry.profile, seed, case_index)
}
roll -= entry.weight
}
}
members[members.length() - 1].profile
}
///|
pub fn gen_valid_profiles() -> Array[GenValidProfile] {
[
NaturalSmallProfile,
NaturalWideProfile,
NaturalDeepProfile,
CoverageForcedPortableProfile,
CoverageForcedAllFeaturesProfile,
BinaryenOraclePortableProfile,
BinaryenOracleRelaxedSimdProfile,
MutationSeedSmallProfile,
MutationSeedRichProfile,
PassFuzzStressProfile,
ValidatorStressProfile,
PassCleanupProfile,
OnceReductionTailCallsProfile,
VacuumProfile,
VacuumCoreProfile,
VacuumTerminalUnreachableProfile,
VacuumStructuralWrappersProfile,
VacuumDroppedParentEffectsProfile,
VacuumConstantResultIfProfile,
VacuumCallPrefixContinuationProfile,
VacuumLocalsetPrefixPreserveProfile,
VacuumHazardBoundaryProfile,
VacuumUnreadTeeProfile,
RseAllProfile,
RseCoreSameValueProfile,
RseLocalCopySelfSetProfile,
RseCfgMergeProfile,
RseLoopFlowProfile,
RseRefinedGetProfile,
RseRefinementWrappersProfile,
RseAggregateRefinalizeProfile,
RseExceptionBoundariesProfile,
RseHazardBoundaryProfile,
RseVacuumTailProfile,
PassDaeProfile,
DaeAllProfile,
ConstraintAllProfile,
ConstraintIntegerProfile,
ConstraintJoinsProfile,
ConstraintLoopsProfile,
ConstraintTeesProfile,
ConstraintWraparoundProfile,
ConstraintI64Profile,
ConstraintLogicalProfile,
ConstraintReferencesProfile,
ConstraintUnreachableProfile,
ConstraintRelationsProfile,
ConstraintEffectsProfile,
ConstraintFloatBoundaryProfile,
Dae2AllProfile,
Dae2ForwardedResultsProfile,
Dae2CyclesProfile,
Dae2ControlFlowProfile,
Dae2EffectfulArgumentsProfile,
Dae2TupleResultsProfile,
Dae2TailCallsProfile,
Dae2IndirectProfile,
Dae2OpenWorldProfile,
Dae2ReferenceTypesProfile,
Binaryen132ArrayMemoryProfile,
Binaryen132WaitqueueProfile,
Binaryen132AtomicOrdersProfile,
Binaryen132DescriptorBranchesProfile,
Binaryen132CompactImportsProfile,
Dae2LocalsProfile,
Dae2ContinuationsProfile,
Dae2ExceptionsProfile,
Dae2CallRefProfile,
Dae2IntrinsicsProfile,
DaeUnusedParamsProfile,
DaeEffectfulArgsProfile,
DaeConstantArgsProfile,
DaeUnusedReturnsProfile,
DaeArgTypeRefinementProfile,
DaeReturnTypeRefinementProfile,
DaeUnseenCallBoundaryProfile,
DaeTailCallBoundaryProfile,
DaeLocalizationProfile,
DaeConvergenceProfile,
DaeOptimizingProfile,
DaeOptimizingCoreProfile,
DaeOptimizingManyTouchedProfile,
DaeOptimizingMediumModuleProfile,
DaeOptimizingLargeLocalsProfile,
DaeOptimizingTouchedCallerProfile,
DaeOptimizingForwardedSuffixProfile,
DaeOptimizingResultControlProfile,
DaeOptimizingStructuredLocalsProfile,
DaeOptimizingReturnCleanupProfile,
DaeOptimizingImmutableFieldProfile,
DaeOptimizingComputedEffectsProfile,
DaeOptimizingTableEffectsProfile,
DaeOptimizingGcComputedProfile,
DaeOptimizingTailBoundaryProfile,
DaeOptimizingTypeReuseProfile,
PassInliningProfile,
InliningOptimizingDirectWrapperProfile,
InliningOptimizingParamSpillProfile,
InliningOptimizingReturnCallProfile,
InliningOptimizingCleanupPayoffProfile,
InliningOptimizingAllProfile,
SgoInitializerFoldingProfile,
SgoSameInitDeadSetProfile,
SgoReadOnlyToWriteProfile,
SgoStartupPropagationProfile,
SgoRuntimePropagationProfile,
SgoNestedCleanupProfile,
SgoAllProfile,
PggDirectGlobalProfile,
PggCompoundGlobalProfile,
PggGcCompoundProfile,
PggDataOffsetProfile,
PggElemOffsetProfile,
PggAllProfile,
PassMemoryProfile,
PassGcRefProfile,
PassControlProfile,
NoImportsProfile,
ImportsHeavyProfile,
GcHeavyProfile,
SimdHeavyProfile,
RelaxedSimdProfile,
MemoryHeavyProfile,
ControlHeavyProfile,
TopologyHeavyProfile,
PathologicalValidProfile,
EngineStateScalarControlProfile,
EngineStateCallsProfile,
EngineStateMemoryProfile,
EngineStateTableProfile,
EngineStateSimdProfile,
EngineStateImportsProfile,
EngineStateInitializationProfile,
EngineStateTrapProfile,
EngineStateMixedProfile,
EngineStateTopologyProfile,
EngineStateEffectsProfile,
EngineStateResourcesProfile,
EngineStateBoundariesProfile,
EngineStateOptimizerShapesProfile,
EngineStateEquivalentFamiliesProfile,
EngineStatePassiveSegmentsProfile,
EngineStateInstantiationBoundariesProfile,
EngineStateMultiResourceProfile,
EngineStateStackPressureProfile,
EngineStateMemoryAliasingProfile,
EngineStateIndirectTrapsProfile,
EngineStateTrapPlacementProfile,
EngineStateCrossInstanceProfile,
EngineStateResourceExhaustionProfile,
EngineStateDecoderTopologyProfile,
EngineStateTailCallsProfile,
EngineStateTypedFunctionReferencesProfile,
EngineStateMemory64Profile,
EngineStateExceptionsProfile,
EngineStateGcProfile,
EngineStateLinkGraphProfile,
EngineStateGcGraphProfile,
EngineStateInitializationGraphProfile,
EngineStateExceptionUnwindProfile,
EngineStateTypeCallMatrixProfile,
EngineStateLebIndexBoundariesProfile,
EngineStateTableReferenceMatrixProfile,
EngineStateMemory64MultiMemoryProfile,
EngineStateTrapCommitMatrixProfile,
EngineStateMetamorphicTwinsProfile,
EngineStateCompilerBoundariesProfile,
EngineStateNanProfile,
EngineStateInvalidModuleProfile,
EngineStateRecursiveMultivalueProfile,
EngineStateSubtypeCastGraphProfile,
EngineStateAllProfile,
EngineStateCoreProfile,
EngineTieringLoopProfile,
EngineTieringLargeFunctionProfile,
EngineTieringCallChainProfile,
EngineTieringCallFanoutProfile,
EngineTieringIndirectProfile,
EngineTieringLocalsStackProfile,
EngineTieringMemoryProfile,
EngineTieringGcProfile,
EngineTieringStressProfile,
SemanticEffectsProfile,
SemanticImportEventsProfile,
SemanticTrapFrontierProfile,
SemanticResourcesProfile,
SemanticOptimizerAllProfile,
GsiDescCastPositiveProfile,
GsiDescCastZeroBoundaryProfile,
GsiDescCastMultiBoundaryProfile,
GsiDescCastStrictSubtypeProfile,
GsiDescCastUnreachableBoundaryProfile,
GsiDescCastAllProfile,
PrecomputeScalarProfile,
PrecomputeScalarValueProfile,
PrecomputeGcValueProfile,
PrecomputeEffectfulValueProfile,
PrecomputeControlProfile,
PrecomputeGlobalProfile,
PrecomputeDropCleanupProfile,
PrecomputeEffectBoundaryProfile,
PrecomputeGcAtomicBoundaryProfile,
PrecomputeDirectPrefixWatchProfile,
PrecomputePropagateLocalFactsProfile,
PrecomputeAllProfile,
PickLoadSignsSignedExtendProfile,
PickLoadSignsSignedShiftProfile,
PickLoadSignsUnsignedMaskProfile,
PickLoadSignsUnsignedShiftProfile,
PickLoadSignsUnknownUseBoundaryProfile,
PickLoadSignsMixedWidthBoundaryProfile,
PickLoadSignsWidthMismatchBoundaryProfile,
PickLoadSignsTeeBoundaryProfile,
PickLoadSignsNoMemoryBoundaryProfile,
PickLoadSignsImportedMemoryProfile,
PickLoadSignsI64WatchProfile,
PickLoadSignsAllProfile,
CodePushingIfArmProfile,
CodePushingAfterIfProfile,
CodePushingDroppedIfProfile,
CodePushingBrIfProfile,
CodePushingBrOnNullProfile,
CodePushingBrOnNonNullProfile,
CodePushingBrOnNonNullPrefixProfile,
CodePushingBrOnCastProfile,
CodePushingBrOnCastFailProfile,
CodePushingBrIfValueProfile,
CodePushingMultiSetProfile,
CodePushingMultiSetDroppedIfProfile,
CodePushingMultiSetBrIfProfile,
CodePushingMultiSetLocalCopyProfile,
CodePushingMultiSetNopWindowProfile,
CodePushingLoopBrIfProfile,
CodePushingMultiSetDropWindowProfile,
CodePushingMultiSetLocalGetWindowProfile,
CodePushingMultiSetGlobalGetWindowProfile,
CodePushingZeroReadProfile,
CodePushingAllProfile,
MergeBlocksStructuralProfile,
MergeBlocksExpressionProfile,
MergeBlocksEffectProfile,
MergeBlocksEhAtomicProfile,
MergeBlocksAllProfile,
RumeDeadGraphProfile,
RumeTableTrapProfile,
RumeLegacyEhProfile,
RumeSpecialImportsProfile,
RumeCallableReferencesProfile,
RumeContinuationsDescriptorsProfile,
RumeIndexRemapStressProfile,
RumeAllProfile,
ReorderGlobalsHotTrafficProfile,
ReorderGlobalsDependencySearchProfile,
ReorderGlobalsImportedProfile,
ReorderGlobalsModuleCodeProfile,
ReorderGlobalsLegacyEhProfile,
ReorderGlobalsMetadataRemapProfile,
ReorderGlobalsThresholdProfile,
ReorderGlobalsAllProfile,
GlobalRefiningPrivateWritesProfile,
GlobalRefiningExportBoundariesProfile,
GlobalRefiningImportAliasesProfile,
GlobalRefiningSubtypeJoinsProfile,
GlobalRefiningAllProfile,
CodeFoldingIfArmsProfile,
CodeFoldingBlockExitsProfile,
CodeFoldingReturnsProfile,
CodeFoldingTailCallsProfile,
CodeFoldingMovementProfile,
CodeFoldingEhProfile,
CodeFoldingAllProfile,
TupleOptimizationSpillProfile,
TupleOptimizationCopyChainProfile,
TupleOptimizationTeeProfile,
TupleOptimizationAliasCapturesProfile,
TupleOptimizationAllProfile,
DeadCodeEliminationNonControlProfile,
DeadCodeEliminationBlockSuffixProfile,
DeadCodeEliminationIfBothArmsProfile,
DeadCodeEliminationIfConditionProfile,
DeadCodeEliminationLoopBodyProfile,
DeadCodeEliminationTryTableProfile,
DeadCodeEliminationTryTableCatchRefProfile,
DeadCodeEliminationBranchPayloadForwarderProfile,
DeadCodeEliminationPrefixBranchPayloadProfile,
DeadCodeEliminationSplitLocalSetWrapperProfile,
DeadCodeEliminationStructuredPrefixProfile,
DeadCodeEliminationEffectfulStructuredPrefixProfile,
DeadCodeEliminationAllProfile,
HsoTeeProfile,
HsoChainProfile,
HsoDefaultProfile,
HsoSideEffectsProfile,
HsoDescriptorProfile,
HsoControlFlowProfile,
HsoSwapProfile,
HsoSharedOrderingProfile,
HsoBoundariesProfile,
HeapStoreOptimizationProfile,
MemoryPackingActiveRangesProfile,
MemoryPackingActiveTrapsProfile,
MemoryPackingDefinedOverlapProfile,
MemoryPackingPassiveSplitsProfile,
MemoryPackingSegmentOpsProfile,
MemoryPackingMemory64Profile,
MemoryPackingBoundariesProfile,
MemoryPackingImportedOverlapProfile,
MemoryPackingAllProfile,
Heap2LocalStructProfile,
Heap2LocalArrayProfile,
Heap2LocalRefProfile,
Heap2LocalOwnerUpdatesProfile,
Heap2LocalAllProfile,
LocalSubtypingStraightLineProfile,
LocalSubtypingStructuredProfile,
LocalSubtypingUnreachableTailProfile,
LocalSubtypingLubsProfile,
LocalSubtypingIterationProfile,
LocalSubtypingNullBottomProfile,
LocalSubtypingControlRefinalizeProfile,
LocalSubtypingAllProfile,
CoalesceLocalsStraightLineProfile,
CoalesceLocalsStructuredProfile,
CoalesceLocalsLoopCopyThroughProfile,
CoalesceLocalsEntryValuesProfile,
CoalesceLocalsCopyPreferenceProfile,
CoalesceLocalsTeeCopiesProfile,
CoalesceLocalsInterBlockProfile,
CoalesceLocalsUnreachableProfile,
CoalesceLocalsLegacyEhProfile,
CoalesceLocalsLargeUnusedProfile,
CoalesceLocalsExactTypesProfile,
CoalesceLocalsAllProfile,
MergeLocalsForwardProfile,
MergeLocalsForwardMultipleProfile,
MergeLocalsPartialInfluenceProfile,
MergeLocalsReverseProfile,
MergeLocalsReverseBoundaryProfile,
MergeLocalsControlProfile,
MergeLocalsTeeProfile,
MergeLocalsMergeBoundaryProfile,
MergeLocalsTypeBoundaryProfile,
MergeLocalsRollbackProfile,
MergeLocalsReverseRollbackProfile,
MergeLocalsNestedCopiesProfile,
MergeLocalsTrivialConfusionProfile,
MergeLocalsUnreachableProfile,
MergeLocalsLegacyEhProfile,
MergeLocalsAllProfile,
RemoveUnusedBrsControlProfile,
RemoveUnusedBrsSwitchProfile,
RemoveUnusedBrsGcProfile,
RemoveUnusedBrsCleanupProfile,
RemoveUnusedBrsConstantBrIfProfile,
RemoveUnusedBrsSingleTargetBrTableProfile,
RemoveUnusedBrsMultiFunctionProfile,
RemoveUnusedBrsResultRefinalizeProfile,
RemoveUnusedBrsMultivalueDropProfile,
RemoveUnusedBrsWrapperCleanupProfile,
RemoveUnusedBrsSelectifyProfile,
RemoveUnusedBrsTailFlowProfile,
RemoveUnusedBrsOneArmIfProfile,
RemoveUnusedBrsLoopProfile,
RemoveUnusedBrsSinkBlocksProfile,
RemoveUnusedBrsEhProfile,
RemoveUnusedBrsJumpThreadProfile,
RemoveUnusedBrsTablifyProfile,
RemoveUnusedBrsOptimizeSetIfProfile,
RemoveUnusedBrsRestructureIfProfile,
RemoveUnusedBrsAdjacentBranchProfile,
RemoveUnusedBrsWinBoundaryProfile,
RemoveUnusedBrsAllProfile,
DuplicateImportEliminationFunctionsProfile,
DuplicateImportEliminationIdentityProfile,
DuplicateImportEliminationModuleCodeProfile,
DuplicateImportEliminationLegacyEhProfile,
DuplicateImportEliminationNonfunctionProfile,
DuplicateImportEliminationAllProfile,
LocalCseTriggerProfile,
DuplicateFunctionEliminationTriggerProfile,
MergeSimilarFunctionsLiteralsProfile,
MergeSimilarFunctionsRepeatedDiffProfile,
MergeSimilarFunctionsExactDuplicatesProfile,
MergeSimilarFunctionsDuplicateTypesProfile,
MergeSimilarFunctionsLocalsProfile,
MergeSimilarFunctionsNestedProfile,
MergeSimilarFunctionsCallTargetsProfile,
MergeSimilarFunctionsTailCallsProfile,
MergeSimilarFunctionsRecordCopyProfile,
MergeSimilarFunctionsAllProfile,
SsaNomergeCoverageProfile,
SsaNomergeSmokeProfile,
SsaNomergeParityProfile,
SsaNomergeStressProfile,
SsaNomergeAllProfile,
SsaFreshSetProfile,
SsaFreshTeeProfile,
SsaParamEntryProfile,
SsaDefaultNumericProfile,
SsaDefaultRefProfile,
SsaUnreachableProfile,
SsaMergeExplicitProfile,
SsaMergeParamEntryProfile,
SsaMergeDefaultEntryProfile,
SsaMergeSharedSetsProfile,
SsaLoopProfile,
SsaBranchProfile,
SsaTypedControlProfile,
SsaNestedValueProfile,
SsaEhProfile,
SsaAllProfile,
SimplifyLocalsLocalTrafficProfile,
SimplifyLocalsStructureResultProfile,
SimplifyLocalsFlatParentProfile,
SimplifyLocalsEffectOrderProfile,
SimplifyLocalsStressProfile,
SimplifyLocalsFamilyCoverageProfile,
SimplifyLocalsAllProfile,
SimplifyLocalsNoteeAllProfile,
SimplifyLocalsNoteeNostructureAllProfile,
SimplifyLocalsNonestingAllProfile,
SimplifyLocalsNostructureStraightLineProfile,
SimplifyLocalsNostructureTeeControlProfile,
SimplifyLocalsNostructureEffectOrderProfile,
SimplifyLocalsNostructureAllProfile,
ReorderLocalsHotSortProfile,
ReorderLocalsPermutationOnlyProfile,
ReorderLocalsFirstUseTiesProfile,
ReorderLocalsMixedTypesProfile,
ReorderLocalsReferenceTypesProfile,
ReorderLocalsUnusedTrimProfile,
ReorderLocalsStructuredProfile,
ReorderLocalsLegacyEhProfile,
ReorderLocalsMultiFunctionProfile,
ReorderLocalsNameRepairProfile,
ReorderLocalsAllProfile,
OptimizeCastsLaterReuseProfile,
OptimizeCastsEarlyMotionProfile,
OptimizeCastsBarriersProfile,
OptimizeCastsBestCastProfile,
OptimizeCastsRefAsProfile,
OptimizeCastsStaticFoldsProfile,
OptimizeCastsNeighborhoodProfile,
OptimizeCastsAllProfile,
PassOiDefaultScalarProfile,
PassOiLocalFactsProfile,
PassOiBooleanSelectProfile,
PassOiMemoryBulkProfile,
PassOiCallRefProfile,
PassOiRefGcProfile,
PassOiGcAggregateProfile,
PassOiDescriptorGcProfile,
PassOiTupleProfile,
PassOiAllProfile,
FlattenFunctionResultsProfile,
FlattenOperandsProfile,
FlattenBlocksProfile,
FlattenIfsProfile,
FlattenLoopsProfile,
FlattenTeeProfile,
FlattenBrProfile,
FlattenBrIfProfile,
FlattenBrTableProfile,
FlattenUnreachableProfile,
FlattenMultivalueProfile,
FlattenLegacyEhProfile,
FlattenAllProfile,
DirectizeConstantProfile,
DirectizeSelectProfile,
DirectizeTableFactsProfile,
DirectizeTailCallProfile,
DirectizeGcProfile,
DirectizeTable64Profile,
DirectizeLegacyEhProfile,
DirectizeBoundaryProfile,
DirectizeAllProfile,
RandomAllProfilesProfile,
CampaignMemory64MultiMemoryProfile,
CampaignEhControlProfile,
CampaignGcRefSubtypesProfile,
CampaignSimdNumericProfile,
CampaignCallTopologyProfile,
CampaignSegmentStateProfile,
EngineCompileShapesProfile,
EngineProposalMatrixProfile,
]
}
///|
pub fn gen_valid_profile_names() -> Array[String] {
gen_valid_profiles().map(gen_valid_profile_name)
}
///|
fn gen_valid_join_profile_names(names : Array[String]) -> String {
let out = StringBuilder::new()
for i = 0; i < names.length(); i = i + 1 {
if i > 0 {
out.write_string("|")
}
out.write_string(names[i])
}
out.to_string()
}
///|
fn gen_valid_normalize_profile_name(input : String) -> String {
let out = StringBuilder::new()
for c in input {
if c >= 'A' && c <= 'Z' {
out.write_char((c.to_int() + 32).unsafe_to_char())
} else if c == '_' || c == ' ' {
out.write_char('-')
} else {
out.write_char(c)
}
}
out.to_string()
}
///|
pub fn gen_valid_profile_by_name(
name : String,
) -> Result[GenValidProfile, String] {
let normalized = gen_valid_normalize_profile_name(name.trim().to_owned())
for profile in gen_valid_profiles() {
if normalized == gen_valid_profile_name(profile) {
return Ok(profile)
}
}
match normalized {
"global-refining" => Ok(GlobalRefiningAllProfile)
"natural" => Ok(NaturalWideProfile)
"coverage-forced" => Ok(CoverageForcedAllFeaturesProfile)
"portable-coverage-forced" => Ok(CoverageForcedPortableProfile)
"binaryen-oracle-coverage-forced" => Ok(BinaryenOraclePortableProfile)
"global-struct-inference-desc-cast" => Ok(GsiDescCastAllProfile)
"gsi-desc-cast-all" => Ok(GsiDescCastAllProfile)
"precompute" => Ok(PrecomputeAllProfile)
"precompute-closeout" => Ok(PrecomputeAllProfile)
"precompute-all-profiles" => Ok(PrecomputeAllProfile)
"precompute-scalar-values" => Ok(PrecomputeScalarValueProfile)
"precompute-gc-values" => Ok(PrecomputeGcValueProfile)
"precompute-effectful-values" => Ok(PrecomputeEffectfulValueProfile)
"precompute-propagate" => Ok(PrecomputeAllProfile)
"precompute-propagate-closeout" => Ok(PrecomputeAllProfile)
"once-reduction" => Ok(OnceReductionTailCallsProfile)
"once-reduction-closeout" => Ok(OnceReductionTailCallsProfile)
"once-reduction-all" => Ok(OnceReductionTailCallsProfile)
"vacuum-closeout" => Ok(VacuumProfile)
"vacuum-all" => Ok(VacuumProfile)
"vacuum-all-profiles" => Ok(VacuumProfile)
"vacuum-current" => Ok(VacuumCoreProfile)
"redundant-set-elimination" => Ok(RseAllProfile)
"rse-closeout" => Ok(RseAllProfile)
"rse-all" => Ok(RseAllProfile)
"rse-all-profiles" => Ok(RseAllProfile)
"dae" => Ok(DaeAllProfile)
"dae-all" => Ok(DaeAllProfile)
"dae-closeout" => Ok(DaeAllProfile)
"dead-argument-elimination-all" => Ok(DaeAllProfile)
"dead-argument-elimination-closeout" => Ok(DaeAllProfile)
"dae-optimizing-closeout" => Ok(DaeOptimizingProfile)
"dae-optimizing-all" => Ok(DaeOptimizingProfile)
"dae-optimizing-all-profiles" => Ok(DaeOptimizingProfile)
"pass-dae-closeout" => Ok(DaeAllProfile)
"pick-load-signs" => Ok(PickLoadSignsAllProfile)
"pick-load-signs-closeout" => Ok(PickLoadSignsAllProfile)
"pick-load-signs-all-profiles" => Ok(PickLoadSignsAllProfile)
"code-pushing" => Ok(CodePushingAllProfile)
"code-pushing-closeout" => Ok(CodePushingAllProfile)
"code-pushing-all-profiles" => Ok(CodePushingAllProfile)
"merge-blocks" | "merge-blocks-closeout" | "merge-blocks-all-profiles" =>
Ok(MergeBlocksAllProfile)
"remove-unused-module-elements"
| "rume"
| "rume-closeout"
| "rume-all-profiles" => Ok(RumeAllProfile)
"reorder-globals"
| "reorder-globals-closeout"
| "reorder-globals-all-profiles" => Ok(ReorderGlobalsAllProfile)
"code-folding" | "code-folding-closeout" | "code-folding-all-profiles" =>
Ok(CodeFoldingAllProfile)
"tuple-optimization" => Ok(TupleOptimizationAllProfile)
"tuple-optimization-closeout" => Ok(TupleOptimizationAllProfile)
"tuple-optimization-all-profiles" => Ok(TupleOptimizationAllProfile)
"dce" => Ok(DeadCodeEliminationAllProfile)
"dead-code-elimination" => Ok(DeadCodeEliminationAllProfile)
"dead-code-elimination-closeout" => Ok(DeadCodeEliminationAllProfile)
"hso"
| "heap-store-optimization-closeout"
| "heap-store-optimization-all"
| "heap-store-optimization-all-profiles" => Ok(HeapStoreOptimizationProfile)
"memory-packing"
| "memory-packing-closeout"
| "memory-packing-all-profiles" => Ok(MemoryPackingAllProfile)
"mp" | "mp-closeout" => Ok(MemoryPackingAllProfile)
"memory-packing-imported" | "memory-packing-zero-filled" =>
Ok(MemoryPackingImportedOverlapProfile)
"heap2local" => Ok(Heap2LocalAllProfile)
"heap-to-local" => Ok(Heap2LocalAllProfile)
"h2l" => Ok(Heap2LocalAllProfile)
"heap2local-closeout" => Ok(Heap2LocalAllProfile)
"heap2local-all-profiles" => Ok(Heap2LocalAllProfile)
"local-subtyping" => Ok(LocalSubtypingAllProfile)
"local-subtyping-closeout" => Ok(LocalSubtypingAllProfile)
"local-subtyping-all-profiles" => Ok(LocalSubtypingAllProfile)
"ls" => Ok(LocalSubtypingAllProfile)
"ls-closeout" => Ok(LocalSubtypingAllProfile)
"coalesce-locals" => Ok(CoalesceLocalsAllProfile)
"coalesce-locals-closeout" => Ok(CoalesceLocalsAllProfile)
"coalesce-locals-all-profiles" => Ok(CoalesceLocalsAllProfile)
"cl" => Ok(CoalesceLocalsAllProfile)
"cl-closeout" => Ok(CoalesceLocalsAllProfile)
"merge-locals" => Ok(MergeLocalsAllProfile)
"merge-locals-closeout" => Ok(MergeLocalsAllProfile)
"merge-locals-all-profiles" => Ok(MergeLocalsAllProfile)
"ml" => Ok(MergeLocalsAllProfile)
"ml-closeout" => Ok(MergeLocalsAllProfile)
"remove-unused-brs" => Ok(RemoveUnusedBrsAllProfile)
"remove-unused-brs-closeout" => Ok(RemoveUnusedBrsAllProfile)
"remove-unused-brs-all-profiles" => Ok(RemoveUnusedBrsAllProfile)
"rub" => Ok(RemoveUnusedBrsAllProfile)
"rub-closeout" => Ok(RemoveUnusedBrsAllProfile)
"duplicate-import-elimination-closeout" =>
Ok(DuplicateImportEliminationAllProfile)
"duplicate-import-elimination-all" =>
Ok(DuplicateImportEliminationAllProfile)
"duplicate-import-elimination-all-profiles" =>
Ok(DuplicateImportEliminationAllProfile)
"die" => Ok(DuplicateImportEliminationAllProfile)
"die-closeout" => Ok(DuplicateImportEliminationAllProfile)
"merge-similar-functions"
| "merge-similar-functions-closeout"
| "merge-similar-functions-all-profiles"
| "msf"
| "msf-closeout" => Ok(MergeSimilarFunctionsAllProfile)
"flatten" => Ok(FlattenAllProfile)
"flatten-closeout" => Ok(FlattenAllProfile)
"flatten-all-profiles" => Ok(FlattenAllProfile)
"directize" | "directize-closeout" | "directize-all-profiles" =>
Ok(DirectizeAllProfile)
"all-profiles" => Ok(RandomAllProfilesProfile)
"random-profiles" => Ok(RandomAllProfilesProfile)
"ssa-nomerge" => Ok(SsaNomergeCoverageProfile)
"ssa-nomerge-closeout" => Ok(SsaNomergeAllProfile)
"ssa" | "ssa-closeout" | "ssa-all-profiles" => Ok(SsaAllProfile)
"simplify-locals"
| "simplify-locals-closeout"
| "simplify-locals-all-profiles" => Ok(SimplifyLocalsAllProfile)
"simplify-locals-notee"
| "simplify-locals-no-tee"
| "simplify-locals-notee-closeout" => Ok(SimplifyLocalsNoteeAllProfile)
"simplify-locals-notee-nostructure"
| "simplify-locals-no-tee-no-structure"
| "simplify-locals-notee-nostructure-closeout" =>
Ok(SimplifyLocalsNoteeNostructureAllProfile)
"simplify-locals-nonesting"
| "simplify-locals-no-nesting"
| "simplify-locals-nonesting-closeout" =>
Ok(SimplifyLocalsNonestingAllProfile)
"simplify-locals-nostructure" => Ok(SimplifyLocalsNostructureAllProfile)
"simplify-locals-nostructure-closeout" =>
Ok(SimplifyLocalsNostructureAllProfile)
"simplify-locals-nostructure-all-profiles" =>
Ok(SimplifyLocalsNostructureAllProfile)
"slns" => Ok(SimplifyLocalsNostructureAllProfile)
"slns-closeout" => Ok(SimplifyLocalsNostructureAllProfile)
"reorder-locals" => Ok(ReorderLocalsAllProfile)
"reorder-locals-closeout" => Ok(ReorderLocalsAllProfile)
"reorder-locals-all-profiles" => Ok(ReorderLocalsAllProfile)
"optimize-casts" => Ok(OptimizeCastsAllProfile)
"optimize-casts-closeout" => Ok(OptimizeCastsAllProfile)
"optimize-casts-all-profiles" => Ok(OptimizeCastsAllProfile)
"inlining-optimizing" => Ok(InliningOptimizingAllProfile)
"engine-state" => Ok(EngineStateAllProfile)
"engine-state-all-profiles" => Ok(EngineStateAllProfile)
"runtime-callable" => Ok(SemanticOptimizerAllProfile)
"semantic-optimizer" => Ok(SemanticOptimizerAllProfile)
"semantic-optimizer-closeout" => Ok(SemanticOptimizerAllProfile)
"semantic-optimizer-all-profiles" => Ok(SemanticOptimizerAllProfile)
"inlining-optimizing-closeout" => Ok(InliningOptimizingAllProfile)
"inlining-optimizing-all-profiles" => Ok(InliningOptimizingAllProfile)
"io" => Ok(InliningOptimizingAllProfile)
"io-closeout" => Ok(InliningOptimizingAllProfile)
"simplify-globals-optimizing" => Ok(SgoAllProfile)
"simplify-globals-optimizing-closeout" => Ok(SgoAllProfile)
"simplify-globals-optimizing-all-profiles" => Ok(SgoAllProfile)
"sgo" => Ok(SgoAllProfile)
"sgo-closeout" => Ok(SgoAllProfile)
"propagate-globals-globally"
| "propagate-globals-globally-closeout"
| "propagate-globals-globally-all-profiles"
| "pgg"
| "pgg-closeout" => Ok(PggAllProfile)
"oc" => Ok(OptimizeCastsAllProfile)
"oc-closeout" => Ok(OptimizeCastsAllProfile)
"rl" => Ok(ReorderLocalsAllProfile)
"rl-closeout" => Ok(ReorderLocalsAllProfile)
"optimize-instructions" => Ok(PassOiAllProfile)
"optimize-instructions-closeout" => Ok(PassOiAllProfile)
"optimize-instructions-all-profiles" => Ok(PassOiAllProfile)
"oi-all" => Ok(PassOiAllProfile)
"oi-default-scalar" => Ok(PassOiDefaultScalarProfile)
"oi-local-facts" => Ok(PassOiLocalFactsProfile)
"oi-boolean-select" => Ok(PassOiBooleanSelectProfile)
"oi-memory-bulk" => Ok(PassOiMemoryBulkProfile)
"oi-call-ref" => Ok(PassOiCallRefProfile)
"oi-ref-gc" => Ok(PassOiRefGcProfile)
"oi-gc-aggregate" => Ok(PassOiGcAggregateProfile)
"oi-aggregate-gc" => Ok(PassOiGcAggregateProfile)
"oi-descriptor-gc" => Ok(PassOiDescriptorGcProfile)
"oi-desc-gc" => Ok(PassOiDescriptorGcProfile)
"oi-tuple" => Ok(PassOiTupleProfile)
_ =>
Err(
"unknown gen-valid profile '\{name}'; expected \{gen_valid_join_profile_names(gen_valid_profile_names())}",
)
}
}
///|
pub fn gen_valid_dead_argument_elimination_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
let uses_gc = profile == DaeArgTypeRefinementProfile ||
profile == DaeReturnTypeRefinementProfile ||
profile == DaeOptimizingImmutableFieldProfile ||
profile == DaeOptimizingGcComputedProfile
let uses_unseen_call_boundary = profile == DaeUnseenCallBoundaryProfile
let uses_tables = uses_unseen_call_boundary ||
profile == DaeOptimizingTableEffectsProfile
let uses_effectful_args = profile == DaeEffectfulArgsProfile ||
profile == DaeLocalizationProfile ||
profile == DaeOptimizingForwardedSuffixProfile
let uses_globals = uses_effectful_args ||
profile == DaeOptimizingImmutableFieldProfile ||
profile == DaeOptimizingComputedEffectsProfile
let uses_mems = profile == DaeOptimizingComputedEffectsProfile
let body_statements = match profile {
DaeUnusedParamsProfile => 4
DaeEffectfulArgsProfile => 5
DaeConstantArgsProfile => 6
DaeUnusedReturnsProfile => 7
DaeArgTypeRefinementProfile => 8
DaeReturnTypeRefinementProfile => 9
DaeUnseenCallBoundaryProfile => 10
DaeTailCallBoundaryProfile => 11
DaeLocalizationProfile => 12
DaeConvergenceProfile => 13
DaeOptimizingProfile => 14
DaeOptimizingCoreProfile => 15
DaeOptimizingManyTouchedProfile => 16
DaeOptimizingMediumModuleProfile => 17
DaeOptimizingLargeLocalsProfile => 18
DaeOptimizingTouchedCallerProfile => 19
DaeOptimizingForwardedSuffixProfile => 20
DaeOptimizingResultControlProfile => 21
DaeOptimizingStructuredLocalsProfile => 22
DaeOptimizingReturnCleanupProfile => 23
DaeOptimizingImmutableFieldProfile => 24
DaeOptimizingComputedEffectsProfile => 25
DaeOptimizingTableEffectsProfile => 26
DaeOptimizingGcComputedProfile => 27
DaeOptimizingTailBoundaryProfile => 28
DaeOptimizingTypeReuseProfile => 29
_ => 3
}
let defined_funcs = match profile {
DaeConvergenceProfile | DaeOptimizingProfile | DaeOptimizingCoreProfile => 5
DaeEffectfulArgsProfile | DaeLocalizationProfile => 4
DaeOptimizingManyTouchedProfile => 11
DaeOptimizingMediumModuleProfile => 103
DaeOptimizingLargeLocalsProfile => 2
DaeOptimizingTouchedCallerProfile => 3
DaeOptimizingForwardedSuffixProfile => 4
DaeOptimizingResultControlProfile => 3
DaeOptimizingStructuredLocalsProfile => 3
DaeOptimizingReturnCleanupProfile => 3
DaeOptimizingImmutableFieldProfile => 3
DaeOptimizingComputedEffectsProfile => 4
DaeOptimizingTableEffectsProfile => 4
DaeOptimizingGcComputedProfile => 3
DaeOptimizingTailBoundaryProfile => 3
DaeOptimizingTypeReuseProfile => 6
_ => 3
}
let max_locals = match profile {
DaeOptimizingLargeLocalsProfile => 129
DaeOptimizingTouchedCallerProfile
| DaeOptimizingStructuredLocalsProfile
| DaeOptimizingReturnCleanupProfile
| DaeOptimizingImmutableFieldProfile => 3
_ => 2
}
let optimizing_profile = profile == DaeOptimizingProfile ||
profile == DaeOptimizingCoreProfile ||
profile == DaeOptimizingManyTouchedProfile ||
profile == DaeOptimizingMediumModuleProfile ||
profile == DaeOptimizingLargeLocalsProfile ||
profile == DaeOptimizingTouchedCallerProfile ||
profile == DaeOptimizingForwardedSuffixProfile ||
profile == DaeOptimizingResultControlProfile ||
profile == DaeOptimizingStructuredLocalsProfile ||
profile == DaeOptimizingReturnCleanupProfile ||
profile == DaeOptimizingImmutableFieldProfile ||
profile == DaeOptimizingComputedEffectsProfile ||
profile == DaeOptimizingTableEffectsProfile ||
profile == DaeOptimizingGcComputedProfile ||
profile == DaeOptimizingTailBoundaryProfile ||
profile == DaeOptimizingTypeReuseProfile
GenValidConfig::{
..base,
max_type_defs: if uses_gc {
6
} else {
3
},
max_imports: 0,
max_defined_funcs: defined_funcs,
max_tables: if uses_tables {
1
} else {
0
},
max_mems: if uses_mems {
1
} else {
0
},
max_globals: if uses_globals {
1
} else {
0
},
max_tags: 0,
max_elems: if uses_unseen_call_boundary {
1
} else {
0
},
max_datas: 0,
max_params: 3,
max_results: if profile == DaeReturnTypeRefinementProfile {
2
} else {
1
},
max_locals,
max_body_statements: body_statements,
max_body_depth: if optimizing_profile {
2
} else {
1
},
max_module_byte_size_budget: Some(30000 + body_statements),
features: GenValidFeatureToggles::{
allow_imports: false,
allow_tables: uses_tables,
allow_mems: uses_mems,
allow_globals: uses_globals,
allow_tags: false,
allow_start: false,
allow_elems: uses_unseen_call_boundary,
allow_datas: false,
allow_ref_types: uses_gc || uses_tables,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: true,
allow_call_indirect: uses_unseen_call_boundary,
allow_tail_calls: profile == DaeTailCallBoundaryProfile ||
profile == DaeOptimizingTailBoundaryProfile,
allow_branch_heavy_control: profile == DaeConvergenceProfile ||
optimizing_profile,
allow_memory_limit_variants: false,
allow_table_limit_variants: uses_unseen_call_boundary,
allow_const_expr_variants: uses_unseen_call_boundary,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: uses_gc,
allow_name_custom_sections: false,
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_dae_unused_params_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeUnusedParamsProfile)
}
///|
fn gen_valid_is_dae_effectful_args_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeEffectfulArgsProfile)
}
///|
fn gen_valid_is_dae_constant_args_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeConstantArgsProfile)
}
///|
fn gen_valid_is_dae_unused_returns_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeUnusedReturnsProfile)
}
///|
fn gen_valid_is_dae_arg_type_refinement_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeArgTypeRefinementProfile)
}
///|
fn gen_valid_is_dae_return_type_refinement_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeReturnTypeRefinementProfile)
}
///|
fn gen_valid_is_dae_unseen_call_boundary_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeUnseenCallBoundaryProfile)
}
///|
fn gen_valid_is_dae_tail_call_boundary_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeTailCallBoundaryProfile)
}
///|
fn gen_valid_is_dae_localization_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DaeLocalizationProfile)
}
///|
fn gen_valid_is_dae_convergence_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(DaeConvergenceProfile)
}
///|
fn gen_valid_is_dae_optimizing_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(DaeOptimizingProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingCoreProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingManyTouchedProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingMediumModuleProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingLargeLocalsProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingTouchedCallerProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingForwardedSuffixProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingResultControlProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingStructuredLocalsProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingReturnCleanupProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingImmutableFieldProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingComputedEffectsProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingTableEffectsProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingGcComputedProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingTailBoundaryProfile) ||
config == GenValidConfig::for_profile(DaeOptimizingTypeReuseProfile)
}
///|
fn gen_valid_dae_optimizing_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(DaeOptimizingManyTouchedProfile) {
DaeOptimizingManyTouchedProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingMediumModuleProfile) {
DaeOptimizingMediumModuleProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingLargeLocalsProfile) {
DaeOptimizingLargeLocalsProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingTouchedCallerProfile) {
DaeOptimizingTouchedCallerProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingForwardedSuffixProfile) {
DaeOptimizingForwardedSuffixProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingResultControlProfile) {
DaeOptimizingResultControlProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingStructuredLocalsProfile) {
DaeOptimizingStructuredLocalsProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingReturnCleanupProfile) {
DaeOptimizingReturnCleanupProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingImmutableFieldProfile) {
DaeOptimizingImmutableFieldProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingComputedEffectsProfile) {
DaeOptimizingComputedEffectsProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingTableEffectsProfile) {
DaeOptimizingTableEffectsProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingGcComputedProfile) {
DaeOptimizingGcComputedProfile
} else if config ==
GenValidConfig::for_profile(DaeOptimizingTailBoundaryProfile) {
DaeOptimizingTailBoundaryProfile
} else if config == GenValidConfig::for_profile(DaeOptimizingTypeReuseProfile) {
DaeOptimizingTypeReuseProfile
} else {
DaeOptimizingCoreProfile
}
}
///|
fn gen_valid_dae_optimizing_structured_case(seed : UInt64) -> Int32 {
(gen_valid_derive_stream_seed(seed, BodyStream) % 7UL).to_int()
}
///|
fn gen_valid_dae_optimizing_gc_computed_case(seed : UInt64) -> Int32 {
(gen_valid_derive_stream_seed(seed ^ 0x4743UL, BodyStream) % 4UL).to_int()
}
///|
pub fn gen_valid_dae_optimizing_profile_case_label(
profile : GenValidProfile,
seed : UInt64,
) -> String? {
match profile {
DaeOptimizingCoreProfile => Some("dae-optimizing:core-cleanup")
DaeOptimizingManyTouchedProfile => Some("dae-optimizing:many-touched")
DaeOptimizingMediumModuleProfile => Some("dae-optimizing:medium-module")
DaeOptimizingLargeLocalsProfile => Some("dae-optimizing:large-locals")
DaeOptimizingTouchedCallerProfile => Some("dae-optimizing:touched-caller")
DaeOptimizingForwardedSuffixProfile =>
Some("dae-optimizing:forwarded-suffix")
DaeOptimizingResultControlProfile => Some("dae-optimizing:result-control")
DaeOptimizingStructuredLocalsProfile =>
Some(
match gen_valid_dae_optimizing_structured_case(seed) {
0 => "dae-optimizing:structured-copy"
1 => "dae-optimizing:structured-sequential-color"
2 => "dae-optimizing:structured-loop-copy"
3 => "dae-optimizing:structured-branch-result"
4 => "dae-optimizing:structured-if-result"
5 => "dae-optimizing:structured-tee-chain"
_ => "dae-optimizing:structured-nested-block"
},
)
DaeOptimizingReturnCleanupProfile => Some("dae-optimizing:return-cleanup")
DaeOptimizingImmutableFieldProfile => Some("dae-optimizing:immutable-field")
DaeOptimizingComputedEffectsProfile =>
Some("dae-optimizing:computed-effects")
DaeOptimizingTableEffectsProfile => Some("dae-optimizing:table-effects")
DaeOptimizingGcComputedProfile =>
Some(
match gen_valid_dae_optimizing_gc_computed_case(seed) {
0 => "dae-optimizing:gc-struct-new"
1 => "dae-optimizing:gc-array-new"
2 => "dae-optimizing:gc-array-new-default"
_ => "dae-optimizing:gc-array-new-fixed"
},
)
DaeOptimizingTailBoundaryProfile => Some("dae-optimizing:tail-boundary")
DaeOptimizingTypeReuseProfile => Some("dae-optimizing:type-reuse")
_ => None
}
}
///|
fn gen_valid_dae_unused_params_profile_module() -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32(), ValType::i32()], [
ValType::i32(),
]),
),
),
]),
)
.with_func_sec(FuncSec::new([entry_type, helper_type, entry_type]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(10)),
Instruction::i32_const(I32(11)),
Instruction::i32_const(I32(12)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(0U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(20)),
Instruction::i32_const(I32(21)),
Instruction::i32_const(I32(22)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_effectful_args_profile_module() -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32()], [ValType::i32()]),
),
),
]),
)
.with_func_sec(
FuncSec::new([entry_type, helper_type, entry_type, entry_type]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(2U)),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(30)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(2U)),
Instruction::i32_const(I32(8)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_unused_returns_profile_module() -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32()], [ValType::i32()]),
),
),
]),
)
.with_func_sec(FuncSec::new([entry_type, helper_type, entry_type]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(10)),
Instruction::i32_const(I32(11)),
Instruction::call(FuncIdx::new(1U)),
Instruction::drop(),
Instruction::i32_const(I32(12)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(20)),
Instruction::i32_const(I32(21)),
Instruction::call(FuncIdx::new(1U)),
Instruction::drop(),
Instruction::i32_const(I32(22)),
]),
),
]),
)
}
///|
fn gen_valid_dae_arg_type_refinement_profile_module() -> Module {
let base_struct_type = TypeIdx::new(0U)
let leaf_struct_type = TypeIdx::new(1U)
let entry_type = TypeIdx::new(2U)
let helper_type = TypeIdx::new(3U)
let base_ref = ValType::ref_type(
RefType::new(true, HeapType::new(base_struct_type)),
)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::new(false, [], CompType::struct_([]))),
RecType::new(
SubType::new(true, [base_struct_type], CompType::struct_([])),
),
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(CompType::func([base_ref], [ValType::i32()])),
),
]),
)
.with_func_sec(FuncSec::new([entry_type, helper_type, entry_type]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::struct_new_default(leaf_struct_type),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_is_null(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::struct_new_default(leaf_struct_type),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_return_type_refinement_profile_module() -> Module {
let base_struct_type = TypeIdx::new(0U)
let leaf_struct_type = TypeIdx::new(1U)
let entry_type = TypeIdx::new(2U)
let helper_type = TypeIdx::new(3U)
let base_ref = ValType::ref_type(
RefType::new(true, HeapType::new(base_struct_type)),
)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::new(false, [], CompType::struct_([]))),
RecType::new(
SubType::new(true, [base_struct_type], CompType::struct_([])),
),
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(SubType::comp_type(CompType::func([], [base_ref]))),
]),
)
.with_func_sec(FuncSec::new([entry_type, helper_type, entry_type]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::ref_is_null(),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::struct_new_default(leaf_struct_type)]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::ref_is_null(),
]),
),
]),
)
}
///|
fn gen_valid_dae_unseen_call_boundary_profile_module() -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
let funcref_type = RefType::new(true, HeapType::abs(AbsHeapType::func()))
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32()], [ValType::i32()]),
),
),
]),
)
.with_func_sec(FuncSec::new([entry_type, helper_type, entry_type]))
.with_table_sec(
TableSec::new([
Table::new(TableType::new(funcref_type, Limits::i32(1U, Some(1U))), None),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_elem_sec(
ElemSec::new([
Elem::new(
ElemMode::active(
TableIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
ElemKind::func_exprs([
Expr::new([Instruction::ref_func(FuncIdx::new(1U))]),
]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(51)),
Instruction::i32_const(I32(61)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(52)),
Instruction::i32_const(I32(62)),
Instruction::i32_const(I32(0)),
Instruction::call_indirect(helper_type, TableIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_tail_call_boundary_profile_module() -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32()], [ValType::i32()]),
),
),
]),
)
.with_func_sec(FuncSec::new([entry_type, helper_type, entry_type]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(31)),
Instruction::i32_const(I32(41)),
Instruction::return_call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(32)),
Instruction::i32_const(I32(42)),
Instruction::return_call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_constant_args_profile_module() -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32()], [ValType::i32()]),
),
),
]),
)
.with_func_sec(FuncSec::new([entry_type, helper_type, entry_type]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(10)),
Instruction::i32_const(I32(77)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(20)),
Instruction::i32_const(I32(77)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_localization_profile_module() -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32()], [ValType::i32()]),
),
),
]),
)
.with_func_sec(
FuncSec::new([entry_type, helper_type, entry_type, entry_type]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::call(FuncIdx::new(2U))]),
),
Instruction::i32_const(I32(13)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(2)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(70)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::call(FuncIdx::new(2U))]),
),
Instruction::i32_const(I32(14)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_i32_result_type(params : Array[ValType]) -> RecType {
RecType::new(SubType::comp_type(CompType::func(params, [ValType::i32()])))
}
///|
fn gen_valid_dae_optimizing_core_module(ctx : GenValidContext) -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
let base = 100 + ctx.random_int_from(FuncStream, 700)
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
]),
)
.with_func_sec(
FuncSec::new([entry_type, helper_type, entry_type, entry_type, entry_type]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(base + 1)),
Instruction::i32_const(I32(base + 101)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(base + 2)),
Instruction::i32_const(I32(base + 102)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(base + 3)),
Instruction::i32_const(I32(base + 103)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(base + 4)),
Instruction::i32_const(I32(base + 104)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_cleanup_helper(local_count : Int32) -> Func {
Func::new(
Locals::from_types(Array::make(local_count, ValType::i32())),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
]),
)
}
///|
fn gen_valid_dae_optimizing_many_touched_module(
ctx : GenValidContext,
) -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
let func_types : Array[TypeIdx] = []
let funcs : Array[Func] = []
let run_body : Array[Instruction] = []
let base = 1 + ctx.random_int_from(FuncStream, 500)
for helper_idx = 0; helper_idx < 10; helper_idx = helper_idx + 1 {
func_types.push(helper_type)
funcs.push(gen_valid_dae_optimizing_cleanup_helper(1))
run_body.push(Instruction::i32_const(I32(base + helper_idx)))
run_body.push(Instruction::i32_const(I32(7 + helper_idx)))
run_body.push(
Instruction::call(FuncIdx::new(helper_idx.reinterpret_as_uint())),
)
if helper_idx < 9 {
run_body.push(Instruction::drop())
}
}
func_types.push(entry_type)
funcs.push(Func::new(Locals::empty(), Expr::new(run_body)))
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
]),
)
.with_func_sec(FuncSec::new(func_types))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(10U))),
]),
)
.with_code_sec(CodeSec::new(funcs))
}
///|
fn gen_valid_dae_optimizing_medium_module(ctx : GenValidContext) -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
let func_types : Array[TypeIdx] = [helper_type, entry_type]
let funcs : Array[Func] = [
gen_valid_dae_optimizing_cleanup_helper(1),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1 + ctx.random_int_from(FuncStream, 500))),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
]),
),
]
for dummy_idx = 0; dummy_idx < 101; dummy_idx = dummy_idx + 1 {
func_types.push(TypeIdx::new(2U))
funcs.push(Func::new(Locals::empty(), Expr::new([])))
}
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
RecType::new(SubType::comp_type(CompType::func([], []))),
]),
)
.with_func_sec(FuncSec::new(func_types))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(CodeSec::new(funcs))
}
///|
fn gen_valid_dae_optimizing_large_locals_module(
ctx : GenValidContext,
) -> Module {
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(1U), TypeIdx::new(0U)]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
gen_valid_dae_optimizing_cleanup_helper(129),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1 + ctx.random_int_from(FuncStream, 500))),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_touched_caller_module(
ctx : GenValidContext,
) -> Module {
let varying = 11 + ctx.random_int_from(FuncStream, 500)
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(1U), TypeIdx::new(0U), TypeIdx::new(0U)]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::from_types([ValType::i32(), ValType::i32()]),
Expr::new([
Instruction::i32_const(I32(varying)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::i32_const(I32(101)),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(102)),
Instruction::i32_const(I32(8)),
Instruction::call(FuncIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_forwarded_suffix_module(
ctx : GenValidContext,
) -> Module {
let entry_type = TypeIdx::new(0U)
let wrapper_type = TypeIdx::new(1U)
let leaf_type = TypeIdx::new(2U)
let produced = 20 + ctx.random_int_from(FuncStream, 500)
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32()]),
]),
)
.with_func_sec(
FuncSec::new([entry_type, wrapper_type, leaf_type, entry_type]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(3U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(produced)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::call(FuncIdx::new(2U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_eqz(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_result_control_module(
ctx : GenValidContext,
) -> Module {
let first_actual = 1 + ctx.random_int_from(FuncStream, 500)
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(1U)]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::br(LabelIdx::new(0U)),
]),
),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(first_actual)),
Instruction::call(FuncIdx::new(0U)),
Instruction::drop(),
Instruction::i32_const(I32(9)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(first_actual + 1)),
Instruction::call(FuncIdx::new(0U)),
Instruction::drop(),
Instruction::i32_const(I32(10)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_structured_locals_module(
ctx : GenValidContext,
) -> Module {
let body = match gen_valid_dae_optimizing_structured_case(ctx.root_seed) {
0 =>
[
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_get(LocalIdx::new(3U)),
Instruction::drop(),
]),
),
Instruction::local_get(LocalIdx::new(2U)),
]
1 =>
[
Instruction::i32_const(I32(11)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::i32_const(I32(22)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_get(LocalIdx::new(3U)),
]
2 =>
[
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::br_if(LabelIdx::new(0U)),
]),
),
Instruction::local_get(LocalIdx::new(3U)),
]
3 =>
[
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::br(LabelIdx::new(0U)),
]),
),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
]
4 =>
[
Instruction::local_get(LocalIdx::new(1U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(11))],
Some([Instruction::i32_const(I32(22))]),
),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
]
5 =>
[
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_get(LocalIdx::new(3U)),
]
_ =>
[
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
]),
),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
]
}
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(1U)]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i32(), ValType::i32()]),
Expr::new(body),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(101)),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(102)),
Instruction::i32_const(I32(8)),
Instruction::call(FuncIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_return_cleanup_module() -> Module {
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(1U)]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i32(), ValType::i32()]),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::return_(),
Instruction::i32_const(I32(33)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_get(LocalIdx::new(3U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(101)),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(102)),
Instruction::i32_const(I32(8)),
Instruction::call(FuncIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_immutable_field_module() -> Module {
let box_type = TypeIdx::new(0U)
let nullable_box = ValType::ref_type(
RefType::new(true, HeapType::new(box_type)),
)
let nonnull_box = ValType::ref_type(
RefType::new(false, HeapType::new(box_type)),
)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(
SubType::comp_type(
CompType::struct_([
FieldType::new(StorageType::val_type(ValType::i32()), Const),
]),
),
),
gen_valid_dae_optimizing_i32_result_type([nullable_box]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), nonnull_box]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(1U), TypeIdx::new(2U), TypeIdx::new(3U)]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(nonnull_box, false),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::struct_new(box_type),
]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_is_null(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::struct_get(box_type, U32::new(0U)),
Instruction::i32_eqz(),
Instruction::if_(
BlockType::val_type(nullable_box),
[Instruction::ref_null(HeapType::new(box_type))],
Some([Instruction::local_get(LocalIdx::new(1U))]),
),
Instruction::call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_computed_effects_module() -> Module {
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(1U),
TypeIdx::new(1U),
]),
)
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(2)),
Instruction::i32_add(),
Instruction::i32_const(I32(99)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::memory_grow(MemIdx::new(0U)),
Instruction::i32_const(I32(100)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(8)),
Instruction::call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::i32_load(MemArg::new(2U, None, 0UL)),
Instruction::i32_const(I32(101)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(9)),
Instruction::call(FuncIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_table_effects_module() -> Module {
let funcref = RefType::new(true, HeapType::abs(AbsHeapType::func()))
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([
ValType::ref_type(funcref),
ValType::i32(),
]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(2U),
TypeIdx::new(2U),
]),
)
.with_table_sec(
TableSec::new([
Table::new(TableType::new(funcref, Limits::i32(1U, None)), None),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::func())),
Instruction::i32_const(I32(1)),
Instruction::table_grow(TableIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::table_get(TableIdx::new(0U)),
Instruction::i32_const(I32(8)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_gc_computed_module(ctx : GenValidContext) -> Module {
let gc_type = TypeIdx::new(0U)
let gc_ref = ValType::ref_type(RefType::new(false, HeapType::new(gc_type)))
let gc_case = gen_valid_dae_optimizing_gc_computed_case(ctx.root_seed)
let gc_comp_type = if gc_case == 0 {
CompType::struct_([
FieldType::new(StorageType::val_type(ValType::i32()), Const),
])
} else {
CompType::array(FieldType::new(StorageType::val_type(ValType::i32()), Var))
}
let make_actual = fn(value : Int32) -> Array[Instruction] {
match gc_case {
0 =>
[Instruction::i32_const(I32(value)), Instruction::struct_new(gc_type)]
1 =>
[
Instruction::i32_const(I32(value)),
Instruction::i32_const(I32(2)),
Instruction::array_new(gc_type),
]
2 =>
[
Instruction::i32_const(I32(value + 1)),
Instruction::array_new_default(gc_type),
]
_ =>
[
Instruction::i32_const(I32(value)),
Instruction::i32_const(I32(value + 1)),
Instruction::array_new_fixed(gc_type, U32::new(2U)),
]
}
}
let first_call = make_actual(1)
first_call.push(Instruction::i32_const(I32(7)))
first_call.push(Instruction::call(FuncIdx::new(0U)))
let second_call = make_actual(3)
second_call.push(Instruction::i32_const(I32(8)))
second_call.push(Instruction::call(FuncIdx::new(0U)))
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(gc_comp_type)),
gen_valid_dae_optimizing_i32_result_type([gc_ref, ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(1U), TypeIdx::new(2U), TypeIdx::new(2U)]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(Locals::empty(), Expr::new(first_call)),
Func::new(Locals::empty(), Expr::new(second_call)),
]),
)
}
///|
fn gen_valid_dae_optimizing_tail_boundary_module() -> Module {
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(1U)]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(101)),
Instruction::i32_const(I32(7)),
Instruction::return_call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(102)),
Instruction::i32_const(I32(8)),
Instruction::return_call(FuncIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_type_reuse_module() -> Module {
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_dae_optimizing_i32_result_type([ValType::i32(), ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([ValType::i32()]),
gen_valid_dae_optimizing_i32_result_type([]),
]),
)
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(2U),
TypeIdx::new(2U),
TypeIdx::new(2U),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(3U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(0U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(2)),
Instruction::i32_const(I32(8)),
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(3)),
Instruction::i32_const(I32(9)),
Instruction::call(FuncIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(4)),
Instruction::i32_const(I32(10)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_dae_optimizing_profile_module(ctx : GenValidContext) -> Module {
match gen_valid_dae_optimizing_profile_kind(ctx.config) {
DaeOptimizingManyTouchedProfile =>
gen_valid_dae_optimizing_many_touched_module(ctx)
DaeOptimizingMediumModuleProfile =>
gen_valid_dae_optimizing_medium_module(ctx)
DaeOptimizingLargeLocalsProfile =>
gen_valid_dae_optimizing_large_locals_module(ctx)
DaeOptimizingTouchedCallerProfile =>
gen_valid_dae_optimizing_touched_caller_module(ctx)
DaeOptimizingForwardedSuffixProfile =>
gen_valid_dae_optimizing_forwarded_suffix_module(ctx)
DaeOptimizingResultControlProfile =>
gen_valid_dae_optimizing_result_control_module(ctx)
DaeOptimizingStructuredLocalsProfile =>
gen_valid_dae_optimizing_structured_locals_module(ctx)
DaeOptimizingReturnCleanupProfile =>
gen_valid_dae_optimizing_return_cleanup_module()
DaeOptimizingImmutableFieldProfile =>
gen_valid_dae_optimizing_immutable_field_module()
DaeOptimizingComputedEffectsProfile =>
gen_valid_dae_optimizing_computed_effects_module()
DaeOptimizingTableEffectsProfile =>
gen_valid_dae_optimizing_table_effects_module()
DaeOptimizingGcComputedProfile =>
gen_valid_dae_optimizing_gc_computed_module(ctx)
DaeOptimizingTailBoundaryProfile =>
gen_valid_dae_optimizing_tail_boundary_module()
DaeOptimizingTypeReuseProfile =>
gen_valid_dae_optimizing_type_reuse_module()
_ => gen_valid_dae_optimizing_core_module(ctx)
}
}
///|
fn gen_valid_dae_convergence_profile_module() -> Module {
let entry_type = TypeIdx::new(0U)
let helper_type = TypeIdx::new(1U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32()], [ValType::i32()]),
),
),
]),
)
.with_func_sec(
FuncSec::new([entry_type, helper_type, helper_type, entry_type, entry_type]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("main"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(10)),
Instruction::i32_const(I32(20)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::call(FuncIdx::new(2U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::local_get(LocalIdx::new(0U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(30)),
Instruction::i32_const(I32(40)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(50)),
Instruction::i32_const(I32(60)),
Instruction::call(FuncIdx::new(2U)),
]),
),
]),
)
}
///|
pub fn GenValidConfig::for_profile(profile : GenValidProfile) -> GenValidConfig {
match profile {
NaturalSmallProfile =>
GenValidConfig::{
..GenValidConfig::natural_default(),
max_type_defs: 4,
max_imports: 2,
max_defined_funcs: 2,
max_tables: 1,
max_mems: 1,
max_globals: 2,
max_tags: 1,
max_elems: 1,
max_datas: 1,
max_params: 1,
max_locals: 3,
max_body_statements: 4,
}
NaturalWideProfile => GenValidConfig::natural_default()
NaturalDeepProfile =>
GenValidConfig::{
..GenValidConfig::natural_default(),
max_defined_funcs: 8,
max_params: 4,
max_results: 2,
max_locals: 8,
max_body_statements: 16,
max_body_depth: 4,
}
CoverageForcedPortableProfile =>
GenValidConfig::portable_coverage_forced_default()
CoverageForcedAllFeaturesProfile =>
GenValidConfig::coverage_forced_default()
BinaryenOraclePortableProfile =>
GenValidConfig::binaryen_oracle_coverage_forced_default()
BinaryenOracleRelaxedSimdProfile => {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
features: GenValidFeatureToggles::{
..base.features,
allow_v128: true,
allow_relaxed_simd: true,
allow_typed_body_generator: true,
},
}
}
MutationSeedSmallProfile =>
GenValidConfig::{
..GenValidConfig::natural_default(),
max_type_defs: 2,
max_imports: 1,
max_defined_funcs: 2,
max_tables: 1,
max_mems: 1,
max_globals: 1,
max_tags: 1,
max_elems: 1,
max_datas: 1,
max_params: 1,
max_results: 1,
max_locals: 1,
max_body_statements: 3,
max_body_depth: 1,
}
MutationSeedRichProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
max_type_defs: 6,
max_tables: 2,
max_globals: 3,
max_locals: 4,
}
PassFuzzStressProfile =>
GenValidConfig::binaryen_oracle_coverage_forced_default()
ValidatorStressProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
max_type_defs: 6,
max_defined_funcs: 6,
max_globals: 4,
max_params: 3,
max_results: 2,
max_locals: 5,
max_body_statements: 10,
max_body_depth: 3,
}
PassCleanupProfile => {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 4,
max_defined_funcs: 6,
max_params: 2,
max_results: 1,
max_locals: 8,
max_body_statements: 12,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_typed_body_generator: true,
},
}
}
OnceReductionTailCallsProfile => gen_valid_once_reduction_profile_config()
VacuumProfile
| VacuumCoreProfile
| VacuumTerminalUnreachableProfile
| VacuumStructuralWrappersProfile
| VacuumDroppedParentEffectsProfile
| VacuumConstantResultIfProfile
| VacuumCallPrefixContinuationProfile
| VacuumLocalsetPrefixPreserveProfile
| VacuumHazardBoundaryProfile
| VacuumUnreadTeeProfile => gen_valid_vacuum_profile_config(profile)
RseAllProfile
| RseCoreSameValueProfile
| RseLocalCopySelfSetProfile
| RseCfgMergeProfile
| RseLoopFlowProfile
| RseRefinedGetProfile
| RseRefinementWrappersProfile
| RseAggregateRefinalizeProfile
| RseExceptionBoundariesProfile
| RseHazardBoundaryProfile
| RseVacuumTailProfile => gen_valid_rse_profile_config(profile)
ConstraintAllProfile
| ConstraintIntegerProfile
| ConstraintJoinsProfile
| ConstraintLoopsProfile
| ConstraintTeesProfile
| ConstraintWraparoundProfile
| ConstraintI64Profile
| ConstraintLogicalProfile
| ConstraintReferencesProfile
| ConstraintUnreachableProfile
| ConstraintRelationsProfile
| ConstraintEffectsProfile
| ConstraintFloatBoundaryProfile =>
gen_valid_constraint_profile_config(profile)
Dae2AllProfile
| Dae2ForwardedResultsProfile
| Dae2CyclesProfile
| Dae2ControlFlowProfile
| Dae2EffectfulArgumentsProfile
| Dae2TupleResultsProfile
| Dae2TailCallsProfile
| Dae2IndirectProfile
| Dae2OpenWorldProfile
| Dae2ReferenceTypesProfile
| Dae2LocalsProfile
| Dae2ContinuationsProfile
| Dae2ExceptionsProfile
| Dae2CallRefProfile
| Dae2IntrinsicsProfile => gen_valid_dae2_profile_config(profile)
Binaryen132ArrayMemoryProfile => gen_valid_array_memory_config()
Binaryen132WaitqueueProfile => gen_valid_waitqueue_config()
Binaryen132AtomicOrdersProfile => gen_valid_atomic_orders_config()
Binaryen132DescriptorBranchesProfile =>
gen_valid_descriptor_branches_config()
Binaryen132CompactImportsProfile => gen_valid_compact_imports_config()
DaeAllProfile
| DaeUnusedParamsProfile
| DaeEffectfulArgsProfile
| DaeConstantArgsProfile
| DaeUnusedReturnsProfile
| DaeArgTypeRefinementProfile
| DaeReturnTypeRefinementProfile
| DaeUnseenCallBoundaryProfile
| DaeTailCallBoundaryProfile
| DaeLocalizationProfile
| DaeConvergenceProfile
| DaeOptimizingProfile
| DaeOptimizingCoreProfile
| DaeOptimizingManyTouchedProfile
| DaeOptimizingMediumModuleProfile
| DaeOptimizingLargeLocalsProfile
| DaeOptimizingTouchedCallerProfile
| DaeOptimizingForwardedSuffixProfile
| DaeOptimizingResultControlProfile
| DaeOptimizingStructuredLocalsProfile
| DaeOptimizingReturnCleanupProfile
| DaeOptimizingImmutableFieldProfile
| DaeOptimizingComputedEffectsProfile
| DaeOptimizingTableEffectsProfile
| DaeOptimizingGcComputedProfile
| DaeOptimizingTailBoundaryProfile
| DaeOptimizingTypeReuseProfile =>
gen_valid_dead_argument_elimination_profile_config(profile)
PassDaeProfile => {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 8,
max_defined_funcs: 8,
max_globals: 3,
max_params: 4,
max_results: 2,
max_locals: 6,
max_body_statements: 12,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_globals: true,
allow_calls: true,
},
}
}
PassInliningProfile => {
let base = GenValidConfig::coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 0,
max_defined_funcs: 10,
max_tables: 0,
max_mems: 0,
max_globals: 2,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 4,
max_results: 2,
max_locals: 4,
max_body_statements: 10,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_tags: false,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_call_indirect: false,
allow_memory64: false,
allow_atomics: false,
allow_const_expr_variants: false,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
},
}
}
InliningOptimizingDirectWrapperProfile
| InliningOptimizingParamSpillProfile
| InliningOptimizingReturnCallProfile
| InliningOptimizingCleanupPayoffProfile
| InliningOptimizingAllProfile =>
gen_valid_inlining_optimizing_profile_config(profile)
SgoInitializerFoldingProfile
| SgoSameInitDeadSetProfile
| SgoReadOnlyToWriteProfile
| SgoStartupPropagationProfile
| SgoRuntimePropagationProfile
| SgoNestedCleanupProfile
| SgoAllProfile => gen_valid_sgo_profile_config(profile)
PggDirectGlobalProfile
| PggCompoundGlobalProfile
| PggGcCompoundProfile
| PggDataOffsetProfile
| PggElemOffsetProfile
| PggAllProfile => gen_valid_pgg_profile_config(profile)
PassMemoryProfile => {
let base = GenValidConfig::coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 0,
max_mems: 3,
max_datas: 8,
max_locals: 6,
max_body_statements: 14,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_mems: true,
allow_v128: true,
allow_shared_memories: true,
allow_memory64: true,
allow_atomics: true,
allow_typed_body_generator: true,
},
}
}
PassGcRefProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
max_type_defs: 16,
max_defined_funcs: 8,
max_globals: 6,
max_params: 3,
max_results: 2,
max_body_statements: 12,
max_body_depth: 3,
}
PassControlProfile => {
let base = GenValidConfig::coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 0,
max_defined_funcs: 8,
max_params: 3,
max_results: 2,
max_locals: 8,
max_body_statements: 18,
max_body_depth: 5,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_branch_heavy_control: true,
allow_tail_calls: true,
allow_typed_body_generator: true,
},
}
}
NoImportsProfile => {
let base = GenValidConfig::natural_default()
GenValidConfig::{
..base,
max_imports: 0,
section_bias: GenValidSectionBias::{
..base.section_bias,
imports_percent: 0,
},
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
},
}
}
ImportsHeavyProfile =>
GenValidConfig::{
..GenValidConfig::natural_default(),
max_imports: 12,
section_bias: GenValidSectionBias::{
..GenValidSectionBias::natural_default(),
imports_percent: 100,
},
}
GcHeavyProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
max_type_defs: 24,
max_defined_funcs: 6,
}
SimdHeavyProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
features: GenValidFeatureToggles::{
..GenValidFeatureToggles::coverage_forced_default(),
allow_v128: true,
allow_typed_body_generator: true,
},
}
RelaxedSimdProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
features: GenValidFeatureToggles::{
..GenValidFeatureToggles::coverage_forced_default(),
allow_v128: true,
allow_relaxed_simd: true,
allow_typed_body_generator: true,
},
}
MemoryHeavyProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
max_mems: 4,
max_datas: 8,
}
ControlHeavyProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
max_body_statements: 16,
max_body_depth: 4,
features: GenValidFeatureToggles::{
..GenValidFeatureToggles::coverage_forced_default(),
allow_branch_heavy_control: true,
allow_tail_calls: true,
allow_typed_body_generator: true,
},
}
TopologyHeavyProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
max_type_defs: 24,
max_imports: 12,
max_defined_funcs: 18,
max_tables: 5,
max_mems: 4,
max_globals: 8,
max_tags: 4,
max_elems: 6,
max_datas: 6,
}
PathologicalValidProfile =>
GenValidConfig::{
..GenValidConfig::coverage_forced_default(),
max_type_defs: 32,
max_imports: 16,
max_defined_funcs: 24,
max_tables: 6,
max_mems: 4,
max_globals: 12,
max_tags: 4,
max_elems: 12,
max_datas: 12,
max_params: 6,
max_results: 3,
max_locals: 32,
max_body_statements: 48,
max_body_depth: 8,
max_instruction_count_budget: Some(4096),
max_expression_depth_budget: Some(64),
max_module_byte_size_budget: Some(262144),
max_rec_group_size_budget: Some(64),
max_section_count_budget: Some(16),
max_name_length: 256,
max_segment_payload_size: 4096,
}
EngineStateScalarControlProfile
| EngineStateCallsProfile
| EngineStateMemoryProfile
| EngineStateTableProfile
| EngineStateSimdProfile
| EngineStateImportsProfile
| EngineStateInitializationProfile
| EngineStateTrapProfile
| EngineStateMixedProfile
| EngineStateTopologyProfile
| EngineStateEffectsProfile
| EngineStateResourcesProfile
| EngineStateBoundariesProfile
| EngineStateOptimizerShapesProfile
| EngineStateEquivalentFamiliesProfile
| EngineStatePassiveSegmentsProfile
| EngineStateInstantiationBoundariesProfile
| EngineStateMultiResourceProfile
| EngineStateStackPressureProfile
| EngineStateMemoryAliasingProfile
| EngineStateIndirectTrapsProfile
| EngineStateTrapPlacementProfile
| EngineStateCrossInstanceProfile
| EngineStateResourceExhaustionProfile
| EngineStateDecoderTopologyProfile
| EngineStateTailCallsProfile
| EngineStateTypedFunctionReferencesProfile
| EngineStateMemory64Profile
| EngineStateExceptionsProfile
| EngineStateGcProfile
| EngineStateLinkGraphProfile
| EngineStateGcGraphProfile
| EngineStateInitializationGraphProfile
| EngineStateExceptionUnwindProfile
| EngineStateTypeCallMatrixProfile
| EngineStateLebIndexBoundariesProfile
| EngineStateTableReferenceMatrixProfile
| EngineStateMemory64MultiMemoryProfile
| EngineStateTrapCommitMatrixProfile
| EngineStateMetamorphicTwinsProfile
| EngineStateCompilerBoundariesProfile
| EngineStateNanProfile
| EngineStateInvalidModuleProfile
| EngineStateRecursiveMultivalueProfile
| EngineStateSubtypeCastGraphProfile => {
let base = GenValidConfig::portable_coverage_forced_default()
let profile_budget_tag = match profile {
EngineStateScalarControlProfile => 1
EngineStateCallsProfile => 2
EngineStateMemoryProfile => 3
EngineStateTableProfile => 4
EngineStateSimdProfile => 5
EngineStateImportsProfile => 6
EngineStateInitializationProfile => 7
EngineStateTrapProfile => 8
EngineStateMixedProfile => 9
EngineStateTopologyProfile => 10
EngineStateEffectsProfile => 11
EngineStateResourcesProfile => 12
EngineStateBoundariesProfile => 13
EngineStateOptimizerShapesProfile => 14
EngineStateEquivalentFamiliesProfile => 15
EngineStatePassiveSegmentsProfile => 16
EngineStateInstantiationBoundariesProfile => 17
EngineStateMultiResourceProfile => 18
EngineStateStackPressureProfile => 19
EngineStateMemoryAliasingProfile => 20
EngineStateIndirectTrapsProfile => 21
EngineStateTrapPlacementProfile => 22
EngineStateCrossInstanceProfile => 23
EngineStateResourceExhaustionProfile => 24
EngineStateDecoderTopologyProfile => 25
EngineStateTailCallsProfile => 26
EngineStateTypedFunctionReferencesProfile => 27
EngineStateMemory64Profile => 28
EngineStateExceptionsProfile => 29
EngineStateGcProfile => 30
EngineStateLinkGraphProfile => 31
EngineStateGcGraphProfile => 32
EngineStateInitializationGraphProfile => 33
EngineStateExceptionUnwindProfile => 34
EngineStateTypeCallMatrixProfile => 35
EngineStateLebIndexBoundariesProfile => 36
EngineStateTableReferenceMatrixProfile => 37
EngineStateMemory64MultiMemoryProfile => 38
EngineStateTrapCommitMatrixProfile => 39
EngineStateMetamorphicTwinsProfile => 40
EngineStateCompilerBoundariesProfile => 41
EngineStateNanProfile => 42
EngineStateInvalidModuleProfile => 43
EngineStateRecursiveMultivalueProfile => 44
EngineStateSubtypeCastGraphProfile => 45
_ => 0
}
let uses_memory = profile == EngineStateMemoryProfile ||
profile == EngineStateSimdProfile ||
profile == EngineStateImportsProfile ||
profile == EngineStateInitializationProfile ||
profile == EngineStateTrapProfile ||
profile == EngineStateMixedProfile ||
profile == EngineStateEffectsProfile ||
profile == EngineStateResourcesProfile ||
profile == EngineStateBoundariesProfile ||
profile == EngineStatePassiveSegmentsProfile ||
profile == EngineStateInstantiationBoundariesProfile ||
profile == EngineStateMultiResourceProfile ||
profile == EngineStateMemoryAliasingProfile ||
profile == EngineStateTrapPlacementProfile ||
profile == EngineStateCrossInstanceProfile ||
profile == EngineStateResourceExhaustionProfile ||
profile == EngineStateMemory64Profile ||
profile == EngineStateLinkGraphProfile ||
profile == EngineStateInitializationGraphProfile ||
profile == EngineStateMemory64MultiMemoryProfile ||
profile == EngineStateTrapCommitMatrixProfile ||
profile == EngineStateCompilerBoundariesProfile ||
profile == EngineStateExceptionUnwindProfile
let uses_table = profile == EngineStateCallsProfile ||
profile == EngineStateTableProfile ||
profile == EngineStateImportsProfile ||
profile == EngineStateInitializationProfile ||
profile == EngineStateTrapProfile ||
profile == EngineStateMixedProfile ||
profile == EngineStateTopologyProfile ||
profile == EngineStateResourcesProfile ||
profile == EngineStatePassiveSegmentsProfile ||
profile == EngineStateInstantiationBoundariesProfile ||
profile == EngineStateMultiResourceProfile ||
profile == EngineStateIndirectTrapsProfile ||
profile == EngineStateTrapPlacementProfile ||
profile == EngineStateCrossInstanceProfile ||
profile == EngineStateResourceExhaustionProfile ||
profile == EngineStateTypedFunctionReferencesProfile ||
profile == EngineStateLinkGraphProfile ||
profile == EngineStateTypeCallMatrixProfile ||
profile == EngineStateTableReferenceMatrixProfile ||
profile == EngineStateTrapCommitMatrixProfile ||
profile == EngineStateExceptionUnwindProfile
let uses_segments = profile == EngineStateMemoryProfile ||
profile == EngineStateTableProfile ||
profile == EngineStateInitializationProfile ||
profile == EngineStateMixedProfile ||
profile == EngineStateResourcesProfile ||
profile == EngineStatePassiveSegmentsProfile ||
profile == EngineStateInstantiationBoundariesProfile ||
profile == EngineStateMultiResourceProfile ||
profile == EngineStateInitializationGraphProfile ||
profile == EngineStateTableReferenceMatrixProfile ||
profile == EngineStateExceptionUnwindProfile
let wide_stack = profile == EngineStateStackPressureProfile ||
profile == EngineStateCompilerBoundariesProfile
let decoder_topology = profile == EngineStateDecoderTopologyProfile ||
profile == EngineStateLebIndexBoundariesProfile
let gc = profile == EngineStateGcProfile ||
profile == EngineStateGcGraphProfile ||
profile == EngineStateSubtypeCastGraphProfile
let many_functions = profile == EngineStateLebIndexBoundariesProfile ||
profile == EngineStateCompilerBoundariesProfile
GenValidConfig::{
..base,
max_type_defs: if wide_stack || gc {
20
} else {
12
},
max_imports: 9,
max_defined_funcs: if many_functions {
140
} else if decoder_topology {
16
} else {
12
},
max_tables: if profile == EngineStateTableReferenceMatrixProfile {
4
} else if uses_table {
2
} else {
0
},
max_mems: if uses_memory {
if profile == EngineStateMultiResourceProfile ||
profile == EngineStateMemory64MultiMemoryProfile {
2
} else {
1
}
} else {
0
},
max_globals: 12,
max_tags: if profile == EngineStateExceptionsProfile ||
profile == EngineStateExceptionUnwindProfile {
1
} else {
0
},
max_elems: if uses_segments {
4
} else {
0
},
max_datas: if uses_segments {
4
} else {
0
},
max_params: if profile == EngineStateStackPressureProfile {
16
} else {
4
},
max_results: if profile == EngineStateStackPressureProfile {
8
} else {
3
},
max_locals: if profile == EngineStateCompilerBoundariesProfile {
128
} else if wide_stack {
64
} else {
12
},
max_body_statements: if profile == EngineStateCompilerBoundariesProfile {
512
} else {
64 + profile_budget_tag
},
max_body_depth: if profile == EngineStateCompilerBoundariesProfile {
16
} else {
5
},
max_instruction_count_budget: Some(
if many_functions {
4096
} else if wide_stack {
1024
} else {
512
},
),
max_expression_depth_budget: Some(
if profile == EngineStateCompilerBoundariesProfile {
32
} else {
16
},
),
max_module_byte_size_budget: Some(
if many_functions || decoder_topology {
262144
} else {
65536
},
),
max_rec_group_size_budget: Some(if wide_stack || gc { 20 } else { 12 }),
max_section_count_budget: Some(16),
max_name_length: if profile == EngineStateLebIndexBoundariesProfile {
16384
} else if decoder_topology {
512
} else {
96
},
max_segment_payload_size: 4096,
section_bias: GenValidSectionBias::{
imports_percent: 100,
tables_percent: if uses_table {
100
} else {
0
},
mems_percent: if uses_memory {
100
} else {
0
},
globals_percent: 100,
tags_percent: if profile == EngineStateExceptionsProfile ||
profile == EngineStateExceptionUnwindProfile {
100
} else {
0
},
start_percent: 100,
elems_percent: if uses_segments && uses_table {
100
} else {
0
},
datas_percent: if uses_segments && uses_memory {
100
} else {
0
},
},
features: GenValidFeatureToggles::{
allow_imports: true,
allow_tables: uses_table,
allow_mems: uses_memory,
allow_globals: true,
allow_tags: profile == EngineStateExceptionsProfile ||
profile == EngineStateExceptionUnwindProfile,
allow_start: true,
allow_elems: uses_segments && uses_table,
allow_datas: uses_segments && uses_memory,
allow_ref_types: uses_table || gc,
allow_v128: profile == EngineStateSimdProfile ||
profile == EngineStateMixedProfile ||
profile == EngineStateTypeCallMatrixProfile,
allow_relaxed_simd: false,
allow_calls: true,
allow_call_indirect: profile == EngineStateCallsProfile ||
profile == EngineStateTableProfile ||
profile == EngineStateMixedProfile ||
profile == EngineStateTopologyProfile ||
profile == EngineStateResourcesProfile ||
profile == EngineStateIndirectTrapsProfile ||
profile == EngineStateTypedFunctionReferencesProfile ||
profile == EngineStateTypeCallMatrixProfile ||
profile == EngineStateTableReferenceMatrixProfile ||
profile == EngineStateExceptionUnwindProfile,
allow_tail_calls: profile == EngineStateTailCallsProfile ||
profile == EngineStateTypeCallMatrixProfile ||
profile == EngineStateExceptionUnwindProfile,
allow_branch_heavy_control: profile == EngineStateScalarControlProfile ||
profile == EngineStateMixedProfile ||
profile == EngineStateEffectsProfile ||
profile == EngineStateBoundariesProfile ||
profile == EngineStateOptimizerShapesProfile ||
profile == EngineStateEquivalentFamiliesProfile ||
profile == EngineStateStackPressureProfile ||
profile == EngineStateTrapPlacementProfile ||
profile == EngineStateExceptionsProfile ||
profile == EngineStateExceptionUnwindProfile ||
profile == EngineStateTrapCommitMatrixProfile ||
profile == EngineStateCompilerBoundariesProfile ||
profile == EngineStateRecursiveMultivalueProfile,
allow_memory_limit_variants: profile ==
EngineStateMultiResourceProfile,
allow_table_limit_variants: false,
allow_const_expr_variants: profile == EngineStateInitializationProfile ||
profile == EngineStateInitializationGraphProfile,
allow_shared_memories: false,
allow_memory64: profile == EngineStateMemory64Profile ||
profile == EngineStateMemory64MultiMemoryProfile,
allow_atomics: false,
allow_subtyping_topology: gc,
allow_name_custom_sections: decoder_topology,
allow_typed_body_generator: true,
allow_ssa_nomerge_body_generator: false,
allow_heap_store_optimization_body_generator: false,
allow_heap2local_body_generator: false,
},
}
}
EngineStateAllProfile | EngineStateCoreProfile =>
GenValidConfig::for_profile(EngineStateScalarControlProfile)
EngineCompileShapesProfile =>
GenValidConfig::for_profile(FlattenBlocksProfile)
EngineProposalMatrixProfile =>
GenValidConfig::for_profile(CampaignSimdNumericProfile)
EngineTieringLoopProfile
| EngineTieringLargeFunctionProfile
| EngineTieringCallChainProfile
| EngineTieringCallFanoutProfile
| EngineTieringIndirectProfile
| EngineTieringLocalsStackProfile
| EngineTieringMemoryProfile
| EngineTieringGcProfile => gen_valid_engine_tiering_config(profile)
EngineTieringStressProfile =>
GenValidConfig::for_profile(EngineTieringLoopProfile)
SemanticEffectsProfile => {
let base = GenValidConfig::portable_coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 4,
max_defined_funcs: 10,
max_tables: 0,
max_mems: 0,
max_globals: 6,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_body_statements: 24,
section_bias: GenValidSectionBias::{
..base.section_bias,
tables_percent: 0,
mems_percent: 0,
},
max_body_depth: 5,
features: GenValidFeatureToggles::{
..base.features,
allow_calls: true,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_v128: false,
allow_branch_heavy_control: true,
allow_relaxed_simd: false,
allow_table_limit_variants: false,
allow_memory_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_const_expr_variants: false,
allow_typed_body_generator: true,
},
}
}
SemanticImportEventsProfile => {
let base = GenValidConfig::portable_coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 4,
max_defined_funcs: 10,
max_tables: 0,
max_mems: 0,
max_globals: 6,
max_tags: 0,
max_elems: 0,
max_datas: 0,
section_bias: GenValidSectionBias::{
..base.section_bias,
imports_percent: 100,
tables_percent: 0,
mems_percent: 0,
},
features: GenValidFeatureToggles::{
..base.features,
allow_imports: true,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_v128: false,
allow_calls: true,
allow_relaxed_simd: false,
allow_table_limit_variants: false,
allow_memory_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_const_expr_variants: false,
allow_typed_body_generator: true,
},
}
}
SemanticTrapFrontierProfile => {
let base = GenValidConfig::portable_coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 4,
max_defined_funcs: 12,
max_tables: 0,
max_mems: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_body_statements: 32,
section_bias: GenValidSectionBias::{
..base.section_bias,
tables_percent: 0,
mems_percent: 0,
},
max_body_depth: 7,
features: GenValidFeatureToggles::{
..base.features,
allow_call_indirect: true,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_v128: false,
allow_branch_heavy_control: true,
allow_relaxed_simd: false,
allow_table_limit_variants: false,
allow_memory_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_const_expr_variants: false,
allow_typed_body_generator: true,
},
}
}
SemanticResourcesProfile => {
let base = GenValidConfig::portable_coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 4,
max_defined_funcs: 10,
max_tables: 0,
max_mems: 0,
max_globals: 10,
max_elems: 0,
max_datas: 0,
max_segment_payload_size: 1024,
section_bias: GenValidSectionBias::{
..base.section_bias,
tables_percent: 0,
mems_percent: 0,
},
features: GenValidFeatureToggles::{
..base.features,
allow_tables: true,
allow_mems: true,
allow_globals: true,
allow_elems: false,
allow_datas: false,
allow_start: false,
allow_v128: false,
allow_memory64: false,
allow_shared_memories: false,
allow_atomics: false,
allow_relaxed_simd: false,
allow_const_expr_variants: false,
allow_table_limit_variants: false,
allow_memory_limit_variants: false,
allow_typed_body_generator: true,
},
}
}
SemanticOptimizerAllProfile =>
GenValidConfig::for_profile(SemanticEffectsProfile)
GsiDescCastPositiveProfile
| GsiDescCastZeroBoundaryProfile
| GsiDescCastMultiBoundaryProfile
| GsiDescCastStrictSubtypeProfile
| GsiDescCastUnreachableBoundaryProfile =>
gen_valid_gsi_desc_cast_profile_config(profile)
GsiDescCastAllProfile =>
gen_valid_gsi_desc_cast_profile_config(GsiDescCastPositiveProfile)
PrecomputeScalarProfile
| PrecomputeScalarValueProfile
| PrecomputeGcValueProfile
| PrecomputeEffectfulValueProfile
| PrecomputeControlProfile
| PrecomputeGlobalProfile
| PrecomputeDropCleanupProfile
| PrecomputeEffectBoundaryProfile
| PrecomputeGcAtomicBoundaryProfile
| PrecomputeDirectPrefixWatchProfile
| PrecomputePropagateLocalFactsProfile =>
gen_valid_precompute_profile_config(profile)
PrecomputeAllProfile =>
gen_valid_precompute_profile_config(PrecomputeScalarProfile)
PickLoadSignsSignedExtendProfile
| PickLoadSignsSignedShiftProfile
| PickLoadSignsUnsignedMaskProfile
| PickLoadSignsUnsignedShiftProfile
| PickLoadSignsUnknownUseBoundaryProfile
| PickLoadSignsMixedWidthBoundaryProfile
| PickLoadSignsWidthMismatchBoundaryProfile
| PickLoadSignsTeeBoundaryProfile
| PickLoadSignsNoMemoryBoundaryProfile
| PickLoadSignsImportedMemoryProfile
| PickLoadSignsI64WatchProfile =>
gen_valid_pick_load_signs_profile_config(profile)
PickLoadSignsAllProfile =>
gen_valid_pick_load_signs_profile_config(PickLoadSignsSignedExtendProfile)
CodePushingIfArmProfile
| CodePushingAfterIfProfile
| CodePushingDroppedIfProfile
| CodePushingBrIfProfile
| CodePushingBrOnNullProfile
| CodePushingBrOnNonNullProfile
| CodePushingBrOnNonNullPrefixProfile
| CodePushingBrOnCastProfile
| CodePushingBrOnCastFailProfile
| CodePushingBrIfValueProfile
| CodePushingMultiSetProfile
| CodePushingMultiSetDroppedIfProfile
| CodePushingMultiSetBrIfProfile
| CodePushingMultiSetLocalCopyProfile
| CodePushingMultiSetNopWindowProfile
| CodePushingLoopBrIfProfile
| CodePushingMultiSetDropWindowProfile
| CodePushingMultiSetLocalGetWindowProfile
| CodePushingMultiSetGlobalGetWindowProfile
| CodePushingZeroReadProfile =>
gen_valid_code_pushing_profile_config(profile)
CodePushingAllProfile =>
gen_valid_code_pushing_profile_config(CodePushingIfArmProfile)
MergeBlocksStructuralProfile
| MergeBlocksExpressionProfile
| MergeBlocksEffectProfile
| MergeBlocksEhAtomicProfile =>
gen_valid_merge_blocks_profile_config(profile)
MergeBlocksAllProfile =>
gen_valid_merge_blocks_profile_config(MergeBlocksStructuralProfile)
RumeDeadGraphProfile
| RumeTableTrapProfile
| RumeLegacyEhProfile
| RumeSpecialImportsProfile
| RumeCallableReferencesProfile
| RumeContinuationsDescriptorsProfile
| RumeIndexRemapStressProfile => gen_valid_rume_profile_config(profile)
RumeAllProfile => gen_valid_rume_profile_config(RumeDeadGraphProfile)
GlobalRefiningPrivateWritesProfile
| GlobalRefiningExportBoundariesProfile
| GlobalRefiningImportAliasesProfile
| GlobalRefiningSubtypeJoinsProfile =>
gen_valid_global_refining_profile_config(profile)
GlobalRefiningAllProfile =>
gen_valid_global_refining_profile_config(
GlobalRefiningPrivateWritesProfile,
)
ReorderGlobalsHotTrafficProfile
| ReorderGlobalsDependencySearchProfile
| ReorderGlobalsImportedProfile
| ReorderGlobalsModuleCodeProfile
| ReorderGlobalsLegacyEhProfile
| ReorderGlobalsMetadataRemapProfile
| ReorderGlobalsThresholdProfile =>
gen_valid_reorder_globals_profile_config(profile)
ReorderGlobalsAllProfile =>
gen_valid_reorder_globals_profile_config(ReorderGlobalsHotTrafficProfile)
CodeFoldingIfArmsProfile
| CodeFoldingBlockExitsProfile
| CodeFoldingReturnsProfile
| CodeFoldingTailCallsProfile
| CodeFoldingMovementProfile
| CodeFoldingEhProfile => gen_valid_code_folding_profile_config(profile)
CodeFoldingAllProfile =>
gen_valid_code_folding_profile_config(CodeFoldingIfArmsProfile)
TupleOptimizationSpillProfile
| TupleOptimizationCopyChainProfile
| TupleOptimizationTeeProfile =>
gen_valid_tuple_optimization_profile_config(profile)
TupleOptimizationAliasCapturesProfile =>
gen_valid_tuple_alias_captures_config()
TupleOptimizationAllProfile =>
gen_valid_tuple_optimization_profile_config(TupleOptimizationSpillProfile)
DeadCodeEliminationNonControlProfile
| DeadCodeEliminationBlockSuffixProfile
| DeadCodeEliminationIfBothArmsProfile
| DeadCodeEliminationIfConditionProfile
| DeadCodeEliminationLoopBodyProfile
| DeadCodeEliminationTryTableProfile
| DeadCodeEliminationTryTableCatchRefProfile
| DeadCodeEliminationBranchPayloadForwarderProfile
| DeadCodeEliminationPrefixBranchPayloadProfile
| DeadCodeEliminationSplitLocalSetWrapperProfile
| DeadCodeEliminationStructuredPrefixProfile
| DeadCodeEliminationEffectfulStructuredPrefixProfile =>
gen_valid_dead_code_elimination_profile_config(profile)
DeadCodeEliminationAllProfile =>
gen_valid_dead_code_elimination_profile_config(
DeadCodeEliminationNonControlProfile,
)
HsoTeeProfile
| HsoChainProfile
| HsoDefaultProfile
| HsoSideEffectsProfile
| HsoDescriptorProfile
| HsoControlFlowProfile
| HsoSwapProfile
| HsoSharedOrderingProfile
| HsoBoundariesProfile =>
gen_valid_heap_store_optimization_profile_config(profile)
HeapStoreOptimizationProfile =>
gen_valid_heap_store_optimization_profile_config(HsoTeeProfile)
MemoryPackingActiveRangesProfile
| MemoryPackingActiveTrapsProfile
| MemoryPackingDefinedOverlapProfile
| MemoryPackingPassiveSplitsProfile
| MemoryPackingSegmentOpsProfile
| MemoryPackingMemory64Profile
| MemoryPackingBoundariesProfile
| MemoryPackingImportedOverlapProfile =>
gen_valid_memory_packing_profile_config(profile)
MemoryPackingAllProfile =>
gen_valid_memory_packing_profile_config(MemoryPackingActiveRangesProfile)
Heap2LocalStructProfile | Heap2LocalArrayProfile | Heap2LocalRefProfile =>
gen_valid_heap2local_profile_config(profile)
Heap2LocalOwnerUpdatesProfile => gen_valid_heap2local_owner_updates_config()
Heap2LocalAllProfile =>
gen_valid_heap2local_profile_config(Heap2LocalAllProfile)
LocalSubtypingStraightLineProfile
| LocalSubtypingStructuredProfile
| LocalSubtypingUnreachableTailProfile
| LocalSubtypingLubsProfile
| LocalSubtypingIterationProfile
| LocalSubtypingNullBottomProfile
| LocalSubtypingControlRefinalizeProfile =>
gen_valid_local_subtyping_profile_config(profile)
LocalSubtypingAllProfile =>
gen_valid_local_subtyping_profile_config(
LocalSubtypingStraightLineProfile,
)
CoalesceLocalsStraightLineProfile
| CoalesceLocalsStructuredProfile
| CoalesceLocalsLoopCopyThroughProfile
| CoalesceLocalsEntryValuesProfile
| CoalesceLocalsCopyPreferenceProfile
| CoalesceLocalsTeeCopiesProfile
| CoalesceLocalsInterBlockProfile
| CoalesceLocalsUnreachableProfile
| CoalesceLocalsLegacyEhProfile
| CoalesceLocalsLargeUnusedProfile
| CoalesceLocalsExactTypesProfile =>
gen_valid_coalesce_locals_profile_config(profile)
CoalesceLocalsAllProfile =>
gen_valid_coalesce_locals_profile_config(
CoalesceLocalsStraightLineProfile,
)
MergeLocalsForwardProfile
| MergeLocalsForwardMultipleProfile
| MergeLocalsPartialInfluenceProfile
| MergeLocalsReverseProfile
| MergeLocalsReverseBoundaryProfile
| MergeLocalsControlProfile
| MergeLocalsTeeProfile
| MergeLocalsMergeBoundaryProfile
| MergeLocalsTypeBoundaryProfile
| MergeLocalsRollbackProfile
| MergeLocalsReverseRollbackProfile
| MergeLocalsNestedCopiesProfile
| MergeLocalsTrivialConfusionProfile
| MergeLocalsUnreachableProfile
| MergeLocalsLegacyEhProfile =>
gen_valid_merge_locals_profile_config(profile)
MergeLocalsAllProfile =>
gen_valid_merge_locals_profile_config(MergeLocalsForwardProfile)
RemoveUnusedBrsControlProfile
| RemoveUnusedBrsSwitchProfile
| RemoveUnusedBrsGcProfile
| RemoveUnusedBrsCleanupProfile
| RemoveUnusedBrsConstantBrIfProfile
| RemoveUnusedBrsSingleTargetBrTableProfile
| RemoveUnusedBrsMultiFunctionProfile
| RemoveUnusedBrsResultRefinalizeProfile
| RemoveUnusedBrsMultivalueDropProfile
| RemoveUnusedBrsWrapperCleanupProfile
| RemoveUnusedBrsSelectifyProfile
| RemoveUnusedBrsTailFlowProfile
| RemoveUnusedBrsOneArmIfProfile
| RemoveUnusedBrsLoopProfile
| RemoveUnusedBrsSinkBlocksProfile
| RemoveUnusedBrsEhProfile
| RemoveUnusedBrsJumpThreadProfile
| RemoveUnusedBrsTablifyProfile
| RemoveUnusedBrsOptimizeSetIfProfile
| RemoveUnusedBrsRestructureIfProfile
| RemoveUnusedBrsAdjacentBranchProfile
| RemoveUnusedBrsWinBoundaryProfile =>
gen_valid_remove_unused_brs_profile_config(profile)
RemoveUnusedBrsAllProfile =>
gen_valid_remove_unused_brs_profile_config(RemoveUnusedBrsControlProfile)
DuplicateImportEliminationFunctionsProfile
| DuplicateImportEliminationIdentityProfile
| DuplicateImportEliminationModuleCodeProfile
| DuplicateImportEliminationLegacyEhProfile
| DuplicateImportEliminationNonfunctionProfile =>
gen_valid_duplicate_import_elimination_profile_config(profile)
DuplicateImportEliminationAllProfile =>
gen_valid_duplicate_import_elimination_profile_config(
DuplicateImportEliminationFunctionsProfile,
)
LocalCseTriggerProfile | DuplicateFunctionEliminationTriggerProfile =>
gen_valid_undersampled_pass_profile_config(profile)
MergeSimilarFunctionsLiteralsProfile
| MergeSimilarFunctionsRepeatedDiffProfile
| MergeSimilarFunctionsExactDuplicatesProfile
| MergeSimilarFunctionsDuplicateTypesProfile
| MergeSimilarFunctionsLocalsProfile
| MergeSimilarFunctionsNestedProfile
| MergeSimilarFunctionsCallTargetsProfile
| MergeSimilarFunctionsTailCallsProfile
| MergeSimilarFunctionsRecordCopyProfile =>
gen_valid_msf_profile_config(profile)
MergeSimilarFunctionsAllProfile =>
gen_valid_msf_profile_config(MergeSimilarFunctionsLiteralsProfile)
SsaNomergeCoverageProfile
| SsaNomergeSmokeProfile
| SsaNomergeParityProfile
| SsaNomergeStressProfile => gen_valid_ssa_nomerge_profile_config(profile)
SsaNomergeAllProfile =>
gen_valid_ssa_nomerge_profile_config(SsaNomergeCoverageProfile)
SsaFreshSetProfile
| SsaFreshTeeProfile
| SsaParamEntryProfile
| SsaDefaultNumericProfile
| SsaDefaultRefProfile
| SsaUnreachableProfile
| SsaMergeExplicitProfile
| SsaMergeParamEntryProfile
| SsaMergeDefaultEntryProfile
| SsaMergeSharedSetsProfile
| SsaLoopProfile
| SsaBranchProfile
| SsaTypedControlProfile
| SsaNestedValueProfile
| SsaEhProfile => gen_valid_ssa_full_profile_config(profile)
SsaAllProfile => gen_valid_ssa_full_profile_config(SsaMergeExplicitProfile)
SimplifyLocalsLocalTrafficProfile
| SimplifyLocalsStructureResultProfile
| SimplifyLocalsFlatParentProfile
| SimplifyLocalsEffectOrderProfile
| SimplifyLocalsStressProfile => gen_valid_slns_profile_config(profile)
SimplifyLocalsFamilyCoverageProfile =>
gen_valid_simplify_locals_family_profile_config()
SimplifyLocalsAllProfile
| SimplifyLocalsNoteeAllProfile
| SimplifyLocalsNoteeNostructureAllProfile
| SimplifyLocalsNonestingAllProfile =>
gen_valid_slns_profile_config(SimplifyLocalsLocalTrafficProfile)
SimplifyLocalsNostructureStraightLineProfile
| SimplifyLocalsNostructureTeeControlProfile
| SimplifyLocalsNostructureEffectOrderProfile =>
gen_valid_slns_profile_config(profile)
SimplifyLocalsNostructureAllProfile =>
gen_valid_slns_profile_config(
SimplifyLocalsNostructureStraightLineProfile,
)
ReorderLocalsHotSortProfile
| ReorderLocalsPermutationOnlyProfile
| ReorderLocalsFirstUseTiesProfile
| ReorderLocalsMixedTypesProfile
| ReorderLocalsReferenceTypesProfile
| ReorderLocalsUnusedTrimProfile
| ReorderLocalsStructuredProfile
| ReorderLocalsLegacyEhProfile
| ReorderLocalsMultiFunctionProfile
| ReorderLocalsNameRepairProfile =>
gen_valid_reorder_locals_profile_config(profile)
ReorderLocalsAllProfile =>
gen_valid_reorder_locals_profile_config(ReorderLocalsHotSortProfile)
OptimizeCastsLaterReuseProfile
| OptimizeCastsEarlyMotionProfile
| OptimizeCastsBarriersProfile
| OptimizeCastsBestCastProfile
| OptimizeCastsRefAsProfile
| OptimizeCastsStaticFoldsProfile
| OptimizeCastsNeighborhoodProfile =>
gen_valid_optimize_casts_profile_config(profile)
OptimizeCastsAllProfile =>
gen_valid_optimize_casts_profile_config(OptimizeCastsLaterReuseProfile)
PassOiDefaultScalarProfile
| PassOiLocalFactsProfile
| PassOiBooleanSelectProfile
| PassOiMemoryBulkProfile
| PassOiCallRefProfile
| PassOiRefGcProfile
| PassOiGcAggregateProfile
| PassOiDescriptorGcProfile
| PassOiTupleProfile => gen_valid_oi_profile_config(profile)
PassOiAllProfile => gen_valid_oi_profile_config(PassOiDefaultScalarProfile)
FlattenFunctionResultsProfile
| FlattenOperandsProfile
| FlattenBlocksProfile
| FlattenIfsProfile
| FlattenLoopsProfile
| FlattenTeeProfile
| FlattenBrProfile
| FlattenBrIfProfile
| FlattenBrTableProfile
| FlattenUnreachableProfile
| FlattenMultivalueProfile
| FlattenLegacyEhProfile => gen_valid_flatten_profile_config(profile)
FlattenAllProfile =>
gen_valid_flatten_profile_config(FlattenFunctionResultsProfile)
DirectizeConstantProfile
| DirectizeSelectProfile
| DirectizeTableFactsProfile
| DirectizeTailCallProfile
| DirectizeGcProfile
| DirectizeTable64Profile
| DirectizeLegacyEhProfile
| DirectizeBoundaryProfile => gen_valid_directize_profile_config(profile)
DirectizeAllProfile =>
gen_valid_directize_profile_config(DirectizeConstantProfile)
RandomAllProfilesProfile => GenValidConfig::coverage_forced_default()
CampaignMemory64MultiMemoryProfile => gen_valid_campaign_memory64_config()
CampaignEhControlProfile => gen_valid_campaign_eh_control_config()
CampaignGcRefSubtypesProfile => gen_valid_campaign_gc_refs_config()
CampaignSimdNumericProfile => gen_valid_campaign_simd_numeric_config()
CampaignCallTopologyProfile => gen_valid_campaign_call_topology_config()
CampaignSegmentStateProfile => gen_valid_campaign_segment_state_config()
}
}
///|
fn gen_valid_optimize_casts_profile_config(
_profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 6,
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 0,
max_locals: 0,
max_body_statements: 0,
max_body_depth: 3,
features: GenValidFeatureToggles::{
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: true,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_const_expr_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: true,
allow_name_custom_sections: false,
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_reorder_locals_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let legacy_eh = profile == ReorderLocalsLegacyEhProfile
let multi_function = profile == ReorderLocalsMultiFunctionProfile
let name_repair = profile == ReorderLocalsNameRepairProfile
let reference_types = profile == ReorderLocalsReferenceTypesProfile
GenValidConfig::{
..base,
max_type_defs: if legacy_eh || multi_function {
3
} else if reference_types {
2
} else {
1
},
max_imports: if multi_function {
1
} else {
0
},
max_defined_funcs: if legacy_eh ||
multi_function ||
profile == ReorderLocalsUnusedTrimProfile {
2
} else {
1
},
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: if legacy_eh {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: if multi_function || profile == ReorderLocalsHotSortProfile {
2
} else {
0
},
max_results: 0,
max_locals: 18,
max_body_statements: match profile {
ReorderLocalsPermutationOnlyProfile => 18
ReorderLocalsFirstUseTiesProfile => 12
ReorderLocalsUnusedTrimProfile => 10
ReorderLocalsStructuredProfile | ReorderLocalsLegacyEhProfile => 16
ReorderLocalsMultiFunctionProfile => 12
ReorderLocalsNameRepairProfile => 8
_ => 14
},
max_body_depth: if profile == ReorderLocalsStructuredProfile || legacy_eh {
4
} else {
2
},
features: GenValidFeatureToggles::{
..base.features,
allow_imports: multi_function,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: legacy_eh,
allow_elems: false,
allow_datas: false,
allow_ref_types: reference_types,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: profile == ReorderLocalsStructuredProfile ||
legacy_eh,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: reference_types,
allow_name_custom_sections: name_repair || multi_function,
allow_typed_body_generator: true,
},
}
}
///|
fn gen_valid_is_reorder_locals_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(ReorderLocalsHotSortProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsPermutationOnlyProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsFirstUseTiesProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsMixedTypesProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsReferenceTypesProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsUnusedTrimProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsStructuredProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsLegacyEhProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsMultiFunctionProfile) ||
config == GenValidConfig::for_profile(ReorderLocalsNameRepairProfile)
}
///|
fn gen_valid_oi_profile_config(profile : GenValidProfile) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let scalar_only_features = GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
}
match profile {
PassOiDefaultScalarProfile =>
GenValidConfig::{
..base,
max_type_defs: 1,
max_imports: 0,
max_defined_funcs: 2,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 2,
max_results: 1,
max_locals: 4,
max_body_statements: 14,
max_body_depth: 2,
features: scalar_only_features,
}
PassOiLocalFactsProfile =>
GenValidConfig::{
..base,
max_type_defs: 1,
max_imports: 0,
max_defined_funcs: 2,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 3,
max_results: 1,
max_locals: 8,
max_body_statements: 16,
max_body_depth: 2,
features: scalar_only_features,
}
PassOiBooleanSelectProfile =>
GenValidConfig::{
..base,
max_type_defs: 1,
max_imports: 0,
max_defined_funcs: 2,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 2,
max_results: 1,
max_locals: 6,
max_body_statements: 18,
max_body_depth: 4,
features: GenValidFeatureToggles::{
..scalar_only_features,
allow_branch_heavy_control: true,
},
}
PassOiMemoryBulkProfile =>
GenValidConfig::{
..base,
max_type_defs: 2,
max_imports: 0,
max_defined_funcs: 3,
max_tables: 0,
max_mems: 3,
max_globals: 1,
max_tags: 0,
max_elems: 0,
max_datas: 6,
max_params: 3,
max_results: 1,
max_locals: 8,
max_body_statements: 20,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: true,
allow_globals: true,
allow_tags: false,
allow_elems: false,
allow_datas: true,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: true,
allow_table_limit_variants: false,
allow_shared_memories: true,
allow_memory64: true,
allow_atomics: true,
allow_ref_types: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
},
}
PassOiCallRefProfile =>
GenValidConfig::{
..base,
max_type_defs: 10,
max_imports: 0,
max_defined_funcs: 8,
max_tables: 2,
max_mems: 0,
max_globals: 2,
max_tags: 0,
max_elems: 3,
max_datas: 0,
max_params: 4,
max_results: 2,
max_locals: 6,
max_body_statements: 16,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: true,
allow_mems: false,
allow_globals: true,
allow_tags: false,
allow_elems: true,
allow_datas: false,
allow_ref_types: true,
allow_calls: true,
allow_call_indirect: true,
allow_tail_calls: true,
allow_branch_heavy_control: false,
allow_memory64: false,
allow_atomics: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_subtyping_topology: true,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
},
}
PassOiRefGcProfile =>
GenValidConfig::{
..base,
max_type_defs: 18,
max_imports: 0,
max_defined_funcs: 8,
max_tables: 2,
max_mems: 1,
max_globals: 6,
max_tags: 0,
max_elems: 2,
max_datas: 1,
max_params: 4,
max_results: 2,
max_locals: 8,
max_body_statements: 18,
max_body_depth: 4,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tags: false,
allow_ref_types: true,
allow_subtyping_topology: true,
allow_v128: false,
allow_relaxed_simd: false,
allow_typed_body_generator: true,
},
}
PassOiGcAggregateProfile =>
GenValidConfig::{
..base,
max_type_defs: 4,
max_imports: 0,
max_defined_funcs: 3,
max_tables: 0,
max_mems: 0,
max_globals: 1,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 1,
max_locals: 1,
max_body_statements: 14,
max_body_depth: 2,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: true,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: true,
allow_calls: true,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory64: false,
allow_atomics: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
},
}
PassOiDescriptorGcProfile =>
GenValidConfig::{
..base,
max_type_defs: 3,
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 0,
max_locals: 2,
max_body_statements: 16,
max_body_depth: 2,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: true,
allow_calls: false,
allow_call_indirect: false,
allow_branch_heavy_control: false,
allow_memory64: false,
allow_atomics: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_subtyping_topology: true,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
},
}
PassOiTupleProfile =>
GenValidConfig::{
..base,
max_type_defs: 2,
max_imports: 0,
max_defined_funcs: 3,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 4,
max_results: 3,
max_locals: 8,
max_body_statements: 19,
max_body_depth: 4,
features: scalar_only_features,
}
_ => base
}
}
///|
fn gen_valid_gsi_desc_cast_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let max_globals = match profile {
GsiDescCastZeroBoundaryProfile => 0
GsiDescCastMultiBoundaryProfile => 2
_ => 1
}
let max_type_defs = match profile {
GsiDescCastStrictSubtypeProfile => 5
_ => 3
}
let max_body_statements = match profile {
GsiDescCastPositiveProfile => 18
GsiDescCastZeroBoundaryProfile => 4
GsiDescCastMultiBoundaryProfile => 5
GsiDescCastStrictSubtypeProfile => 7
GsiDescCastUnreachableBoundaryProfile => 3
_ => 18
}
GenValidConfig::{
..base,
max_type_defs,
max_defined_funcs: 1,
max_globals,
max_params: 3,
max_results: 0,
max_locals: 0,
max_body_statements,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_globals: max_globals > 0,
allow_ref_types: true,
allow_subtyping_topology: profile == GsiDescCastStrictSubtypeProfile,
},
}
}
///|
fn gen_valid_is_gsi_desc_cast_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(GsiDescCastPositiveProfile) ||
config == GenValidConfig::for_profile(GsiDescCastZeroBoundaryProfile) ||
config == GenValidConfig::for_profile(GsiDescCastMultiBoundaryProfile) ||
config == GenValidConfig::for_profile(GsiDescCastStrictSubtypeProfile) ||
config == GenValidConfig::for_profile(GsiDescCastUnreachableBoundaryProfile)
}
///|
fn gen_valid_precompute_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let body_statements = match profile {
PrecomputeScalarProfile => 11
PrecomputeScalarValueProfile => 19
PrecomputeGcValueProfile => 20
PrecomputeEffectfulValueProfile => 21
PrecomputeControlProfile => 12
PrecomputeGlobalProfile => 13
PrecomputeDropCleanupProfile => 14
PrecomputeEffectBoundaryProfile => 15
PrecomputeGcAtomicBoundaryProfile => 16
PrecomputeDirectPrefixWatchProfile => 17
PrecomputePropagateLocalFactsProfile => 18
_ => 11
}
let max_globals = match profile {
PrecomputeGlobalProfile => 3
PrecomputeEffectBoundaryProfile => 1
PrecomputePropagateLocalFactsProfile => 1
_ => 0
}
let max_mems = match profile {
PrecomputeEffectBoundaryProfile => 1
_ => 0
}
let max_type_defs = match profile {
PrecomputeGcAtomicBoundaryProfile => 4
PrecomputeScalarValueProfile => 4
PrecomputeGcValueProfile => 5
_ => 2
}
GenValidConfig::{
..base,
max_type_defs,
max_imports: 0,
max_defined_funcs: if profile == PrecomputeScalarValueProfile {
26
} else if profile == PrecomputeGcValueProfile {
13
} else if profile == PrecomputeGcAtomicBoundaryProfile {
2
} else if profile == PrecomputeEffectBoundaryProfile ||
profile == PrecomputePropagateLocalFactsProfile {
2
} else {
1
},
max_tables: 0,
max_mems,
max_globals,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: if profile == PrecomputeGcAtomicBoundaryProfile ||
profile == PrecomputePropagateLocalFactsProfile {
1
} else {
0
},
max_results: if profile == PrecomputeDirectPrefixWatchProfile ||
profile == PrecomputeScalarValueProfile ||
profile == PrecomputeGcValueProfile ||
profile == PrecomputeEffectfulValueProfile {
1
} else {
0
},
max_locals: if profile == PrecomputeDirectPrefixWatchProfile ||
profile == PrecomputeEffectfulValueProfile {
1
} else if profile == PrecomputePropagateLocalFactsProfile {
6
} else {
0
},
max_body_statements: body_statements,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: max_mems > 0,
allow_globals: max_globals > 0,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_calls: profile == PrecomputeEffectBoundaryProfile ||
profile == PrecomputeGcAtomicBoundaryProfile ||
profile == PrecomputePropagateLocalFactsProfile,
allow_call_indirect: false,
allow_tail_calls: false,
allow_memory64: false,
allow_atomics: profile == PrecomputeGcAtomicBoundaryProfile,
allow_shared_memories: false,
allow_ref_types: profile == PrecomputeGcAtomicBoundaryProfile ||
profile == PrecomputeGcValueProfile,
allow_v128: false,
allow_relaxed_simd: false,
allow_typed_body_generator: false,
allow_name_custom_sections: false,
},
}
}
///|
fn gen_valid_is_precompute_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(PrecomputeScalarProfile) ||
config == GenValidConfig::for_profile(PrecomputeScalarValueProfile) ||
config == GenValidConfig::for_profile(PrecomputeGcValueProfile) ||
config == GenValidConfig::for_profile(PrecomputeEffectfulValueProfile) ||
config == GenValidConfig::for_profile(PrecomputeControlProfile) ||
config == GenValidConfig::for_profile(PrecomputeGlobalProfile) ||
config == GenValidConfig::for_profile(PrecomputeDropCleanupProfile) ||
config == GenValidConfig::for_profile(PrecomputeEffectBoundaryProfile) ||
config == GenValidConfig::for_profile(PrecomputeGcAtomicBoundaryProfile) ||
config == GenValidConfig::for_profile(PrecomputeDirectPrefixWatchProfile) ||
config == GenValidConfig::for_profile(PrecomputePropagateLocalFactsProfile)
}
///|
fn gen_valid_pick_load_signs_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let body_statements = match profile {
PickLoadSignsSignedExtendProfile => 11
PickLoadSignsSignedShiftProfile => 12
PickLoadSignsUnsignedMaskProfile => 30
PickLoadSignsUnsignedShiftProfile => 40
PickLoadSignsUnknownUseBoundaryProfile => 15
PickLoadSignsMixedWidthBoundaryProfile => 16
PickLoadSignsWidthMismatchBoundaryProfile => 17
PickLoadSignsTeeBoundaryProfile => 18
PickLoadSignsNoMemoryBoundaryProfile => 19
PickLoadSignsImportedMemoryProfile => 20
PickLoadSignsI64WatchProfile => 48
_ => 11
}
GenValidConfig::{
..base,
max_type_defs: if profile == PickLoadSignsUnsignedMaskProfile ||
profile == PickLoadSignsUnsignedShiftProfile {
2
} else {
1
},
max_imports: if profile == PickLoadSignsImportedMemoryProfile {
1
} else {
0
},
max_defined_funcs: if profile == PickLoadSignsUnsignedMaskProfile ||
profile == PickLoadSignsUnsignedShiftProfile {
5
} else if profile == PickLoadSignsI64WatchProfile {
6
} else {
1
},
max_tables: 0,
max_mems: if profile == PickLoadSignsNoMemoryBoundaryProfile ||
profile == PickLoadSignsImportedMemoryProfile {
0
} else {
1
},
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: if profile == PickLoadSignsTeeBoundaryProfile {
0
} else {
1
},
max_locals: 1,
max_body_statements: body_statements,
max_body_depth: 1,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: profile == PickLoadSignsImportedMemoryProfile,
allow_tables: false,
allow_mems: profile != PickLoadSignsNoMemoryBoundaryProfile,
allow_globals: false,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_ref_types: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_subtyping_topology: false,
allow_typed_body_generator: false,
allow_name_custom_sections: false,
},
}
}
///|
fn gen_valid_is_pick_load_signs_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(PickLoadSignsSignedExtendProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsSignedShiftProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsUnsignedMaskProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsUnsignedShiftProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsUnknownUseBoundaryProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsMixedWidthBoundaryProfile) ||
config ==
GenValidConfig::for_profile(PickLoadSignsWidthMismatchBoundaryProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsTeeBoundaryProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsNoMemoryBoundaryProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsImportedMemoryProfile) ||
config == GenValidConfig::for_profile(PickLoadSignsI64WatchProfile)
}
///|
fn gen_valid_code_pushing_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 1,
max_imports: 0,
max_defined_funcs: if profile == CodePushingZeroReadProfile {
3
} else {
1
},
max_tables: 0,
max_mems: 0,
max_globals: if profile == CodePushingMultiSetGlobalGetWindowProfile {
1
} else {
0
},
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: if profile == CodePushingMultiSetLocalCopyProfile {
3
} else if profile == CodePushingMultiSetLocalGetWindowProfile {
2
} else {
1
},
max_results: if profile == CodePushingAfterIfProfile ||
profile == CodePushingBrIfValueProfile ||
profile == CodePushingBrOnNonNullProfile ||
profile == CodePushingBrOnCastProfile ||
profile == CodePushingBrOnCastFailProfile {
1
} else {
0
},
max_locals: if profile == CodePushingMultiSetProfile ||
profile == CodePushingMultiSetDroppedIfProfile ||
profile == CodePushingMultiSetBrIfProfile ||
profile == CodePushingBrOnNullProfile ||
profile == CodePushingBrOnNonNullProfile ||
profile == CodePushingBrOnNonNullPrefixProfile ||
profile == CodePushingBrOnCastProfile ||
profile == CodePushingBrOnCastFailProfile ||
profile == CodePushingMultiSetLocalCopyProfile ||
profile == CodePushingMultiSetNopWindowProfile ||
profile == CodePushingLoopBrIfProfile ||
profile == CodePushingMultiSetDropWindowProfile ||
profile == CodePushingMultiSetLocalGetWindowProfile ||
profile == CodePushingMultiSetGlobalGetWindowProfile {
2
} else {
1
},
max_body_statements: match profile {
CodePushingAfterIfProfile => 8
CodePushingDroppedIfProfile => 9
CodePushingBrIfProfile => 7
CodePushingBrIfValueProfile => 11
CodePushingBrOnNullProfile => 11
CodePushingBrOnNonNullProfile => 10
CodePushingBrOnNonNullPrefixProfile => 16
CodePushingBrOnCastProfile => 12
CodePushingBrOnCastFailProfile => 13
CodePushingMultiSetProfile => 11
CodePushingMultiSetDroppedIfProfile => 12
CodePushingMultiSetBrIfProfile => 13
CodePushingMultiSetLocalCopyProfile => 11
CodePushingMultiSetNopWindowProfile => 14
CodePushingLoopBrIfProfile => 15
CodePushingMultiSetDropWindowProfile => 16
CodePushingMultiSetLocalGetWindowProfile => 16
CodePushingMultiSetGlobalGetWindowProfile => 16
CodePushingZeroReadProfile => 7
_ => 5
},
max_body_depth: 2,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: profile == CodePushingMultiSetGlobalGetWindowProfile,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_ref_types: profile == CodePushingBrOnNullProfile ||
profile == CodePushingBrOnNonNullProfile ||
profile == CodePushingBrOnNonNullPrefixProfile ||
profile == CodePushingBrOnCastProfile ||
profile == CodePushingBrOnCastFailProfile,
allow_v128: false,
allow_relaxed_simd: false,
allow_subtyping_topology: false,
allow_typed_body_generator: false,
allow_name_custom_sections: false,
},
}
}
///|
fn gen_valid_is_code_pushing_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(CodePushingIfArmProfile) ||
config == GenValidConfig::for_profile(CodePushingAfterIfProfile) ||
config == GenValidConfig::for_profile(CodePushingDroppedIfProfile) ||
config == GenValidConfig::for_profile(CodePushingBrIfProfile) ||
config == GenValidConfig::for_profile(CodePushingBrOnNullProfile) ||
config == GenValidConfig::for_profile(CodePushingBrOnNonNullProfile) ||
config == GenValidConfig::for_profile(CodePushingBrOnNonNullPrefixProfile) ||
config == GenValidConfig::for_profile(CodePushingBrOnCastProfile) ||
config == GenValidConfig::for_profile(CodePushingBrOnCastFailProfile) ||
config == GenValidConfig::for_profile(CodePushingBrIfValueProfile) ||
config == GenValidConfig::for_profile(CodePushingMultiSetProfile) ||
config == GenValidConfig::for_profile(CodePushingMultiSetDroppedIfProfile) ||
config == GenValidConfig::for_profile(CodePushingMultiSetBrIfProfile) ||
config == GenValidConfig::for_profile(CodePushingMultiSetLocalCopyProfile) ||
config == GenValidConfig::for_profile(CodePushingMultiSetNopWindowProfile) ||
config == GenValidConfig::for_profile(CodePushingLoopBrIfProfile) ||
config == GenValidConfig::for_profile(CodePushingMultiSetDropWindowProfile) ||
config ==
GenValidConfig::for_profile(CodePushingMultiSetLocalGetWindowProfile) ||
config ==
GenValidConfig::for_profile(CodePushingMultiSetGlobalGetWindowProfile) ||
config == GenValidConfig::for_profile(CodePushingZeroReadProfile)
}
///|
fn gen_valid_tuple_optimization_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 2,
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 2,
max_locals: if profile == TupleOptimizationCopyChainProfile {
4
} else {
2
},
max_body_statements: match profile {
TupleOptimizationCopyChainProfile => 12
TupleOptimizationTeeProfile => 8
_ => 9
},
max_body_depth: 1,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
allow_typed_body_generator: false,
},
}
}
///|
fn gen_valid_is_tuple_optimization_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(TupleOptimizationSpillProfile) ||
config == GenValidConfig::for_profile(TupleOptimizationCopyChainProfile) ||
config == GenValidConfig::for_profile(TupleOptimizationTeeProfile)
}
///|
pub fn gen_valid_tuple_optimization_trigger_profile_case_label(
profile : GenValidProfile,
seed : UInt64,
) -> String? {
match profile {
TupleOptimizationSpillProfile => Some("tuple-optimization:spill")
TupleOptimizationCopyChainProfile => Some("tuple-optimization:copy-chain")
TupleOptimizationTeeProfile => Some("tuple-optimization:tee")
TupleOptimizationAliasCapturesProfile =>
match seed % 3UL {
0UL => Some("tuple-optimization:alias-captures-prefix")
1UL => Some("tuple-optimization:alias-captures-trailing")
_ => Some("tuple-optimization:alias-captures-chain")
}
_ => None
}
}
///|
fn gen_valid_dead_code_elimination_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: if profile == DeadCodeEliminationTryTableCatchRefProfile {
2
} else {
1
},
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: if profile == DeadCodeEliminationTryTableCatchRefProfile {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: if profile == DeadCodeEliminationBranchPayloadForwarderProfile {
1
} else if profile == DeadCodeEliminationSplitLocalSetWrapperProfile {
2
} else {
0
},
max_results: if profile == DeadCodeEliminationBranchPayloadForwarderProfile ||
profile == DeadCodeEliminationPrefixBranchPayloadProfile ||
profile == DeadCodeEliminationSplitLocalSetWrapperProfile {
1
} else {
0
},
max_locals: if profile == DeadCodeEliminationSplitLocalSetWrapperProfile {
2
} else {
0
},
max_body_statements: if profile == DeadCodeEliminationBlockSuffixProfile {
4
} else if profile == DeadCodeEliminationIfBothArmsProfile {
5
} else if profile == DeadCodeEliminationIfConditionProfile {
3
} else if profile == DeadCodeEliminationLoopBodyProfile {
1
} else if profile == DeadCodeEliminationTryTableProfile {
2
} else if profile == DeadCodeEliminationTryTableCatchRefProfile {
3
} else if profile == DeadCodeEliminationBranchPayloadForwarderProfile ||
profile == DeadCodeEliminationPrefixBranchPayloadProfile {
1
} else if profile == DeadCodeEliminationSplitLocalSetWrapperProfile {
3
} else {
6
},
max_body_depth: if profile == DeadCodeEliminationBlockSuffixProfile ||
profile == DeadCodeEliminationIfBothArmsProfile ||
profile == DeadCodeEliminationIfConditionProfile ||
profile == DeadCodeEliminationLoopBodyProfile ||
profile == DeadCodeEliminationTryTableProfile ||
profile == DeadCodeEliminationTryTableCatchRefProfile ||
profile == DeadCodeEliminationBranchPayloadForwarderProfile ||
profile == DeadCodeEliminationPrefixBranchPayloadProfile ||
profile == DeadCodeEliminationStructuredPrefixProfile ||
profile == DeadCodeEliminationEffectfulStructuredPrefixProfile {
1
} else if profile == DeadCodeEliminationSplitLocalSetWrapperProfile {
4
} else {
0
},
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: profile == DeadCodeEliminationEffectfulStructuredPrefixProfile,
allow_globals: false,
allow_tags: profile == DeadCodeEliminationTryTableCatchRefProfile,
allow_elems: false,
allow_datas: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_ref_types: profile == DeadCodeEliminationTryTableCatchRefProfile,
allow_v128: false,
allow_relaxed_simd: false,
allow_subtyping_topology: false,
allow_typed_body_generator: false,
allow_name_custom_sections: false,
},
}
}
///|
fn gen_valid_is_dead_code_elimination_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(DeadCodeEliminationNonControlProfile) ||
config == GenValidConfig::for_profile(DeadCodeEliminationBlockSuffixProfile) ||
config == GenValidConfig::for_profile(DeadCodeEliminationIfBothArmsProfile) ||
config == GenValidConfig::for_profile(DeadCodeEliminationIfConditionProfile) ||
config == GenValidConfig::for_profile(DeadCodeEliminationLoopBodyProfile) ||
config == GenValidConfig::for_profile(DeadCodeEliminationTryTableProfile) ||
config ==
GenValidConfig::for_profile(DeadCodeEliminationTryTableCatchRefProfile) ||
config ==
GenValidConfig::for_profile(DeadCodeEliminationBranchPayloadForwarderProfile) ||
config ==
GenValidConfig::for_profile(DeadCodeEliminationPrefixBranchPayloadProfile) ||
config ==
GenValidConfig::for_profile(DeadCodeEliminationSplitLocalSetWrapperProfile) ||
config ==
GenValidConfig::for_profile(DeadCodeEliminationStructuredPrefixProfile) ||
config ==
GenValidConfig::for_profile(
DeadCodeEliminationEffectfulStructuredPrefixProfile,
)
}
///|
fn gen_valid_memory_packing_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
GenValidConfig::{
..base,
max_imports: 1,
max_defined_funcs: 1,
max_mems: 1,
max_datas: match profile {
MemoryPackingActiveRangesProfile => 41
MemoryPackingActiveTrapsProfile => 42
MemoryPackingDefinedOverlapProfile => 43
MemoryPackingPassiveSplitsProfile => 44
MemoryPackingSegmentOpsProfile => 45
MemoryPackingMemory64Profile => 46
MemoryPackingBoundariesProfile => 47
MemoryPackingImportedOverlapProfile => 48
_ => 41
},
max_params: 1,
max_results: 0,
max_locals: 1,
max_body_statements: 12,
max_body_depth: 3,
max_segment_payload_size: 128,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: true,
allow_tables: false,
allow_mems: true,
allow_globals: false,
allow_tags: false,
allow_elems: false,
allow_datas: true,
allow_ref_types: false,
allow_v128: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_memory64: true,
allow_atomics: false,
allow_shared_memories: false,
allow_name_custom_sections: true,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: false,
},
}
}
///|
fn gen_valid_memory_packing_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
let profiles = [
MemoryPackingActiveRangesProfile,
MemoryPackingActiveTrapsProfile,
MemoryPackingDefinedOverlapProfile,
MemoryPackingPassiveSplitsProfile,
MemoryPackingSegmentOpsProfile,
MemoryPackingMemory64Profile,
MemoryPackingBoundariesProfile,
MemoryPackingImportedOverlapProfile,
]
for profile in profiles {
if config == GenValidConfig::for_profile(profile) {
return profile
}
}
MemoryPackingActiveRangesProfile
}
///|
fn gen_valid_is_memory_packing_profile_config(config : GenValidConfig) -> Bool {
let profile = gen_valid_memory_packing_profile_kind(config)
config == GenValidConfig::for_profile(profile)
}
///|
fn gen_valid_memory_packing_void_func(
body : Array[Instruction],
) -> (TypeSec, FuncSec, CodeSec) {
let type_sec = TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], []))),
])
(
type_sec,
FuncSec::new([TypeIdx::new(0U)]),
CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]),
)
}
///|
fn gen_valid_memory_packing_payload(seed : UInt64) -> Bytes {
let bytes : Array[Byte] = [(65).to_byte()]
let zero_count = 25 + (seed % 37UL).to_int()
for _ in 0.. Module {
let profile = gen_valid_memory_packing_profile_kind(ctx.config)
let memory32 = MemType::new(Limits::i32(1U, None))
let zero_heavy = gen_valid_memory_packing_payload(ctx.root_seed)
let payload_size = zero_heavy.length()
match profile {
MemoryPackingActiveRangesProfile =>
Module::new()
.with_mem_sec(MemSec::new([memory32]))
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
zero_heavy,
),
]),
)
MemoryPackingActiveTrapsProfile =>
Module::new()
.with_mem_sec(MemSec::new([memory32]))
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(65535))]),
),
b"\x00\x00",
),
]),
)
MemoryPackingDefinedOverlapProfile =>
Module::new()
.with_mem_sec(MemSec::new([memory32]))
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
zero_heavy,
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(8))]),
),
b"later",
),
]),
)
MemoryPackingPassiveSplitsProfile => {
let (type_sec, func_sec, code_sec) = gen_valid_memory_packing_void_func([
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(payload_size)),
Instruction::memory_init(DataIdx::new(0U), MemIdx::new(0U)),
Instruction::data_drop(DataIdx::new(0U)),
])
Module::new()
.with_type_sec(type_sec)
.with_func_sec(func_sec)
.with_mem_sec(MemSec::new([memory32]))
.with_data_cnt_sec(DataCntSec::new(U32(1U)))
.with_code_sec(code_sec)
.with_data_sec(DataSec::new([Data::new(DataMode::passive(), zero_heavy)]))
}
MemoryPackingSegmentOpsProfile => {
let (type_sec, func_sec, code_sec) = gen_valid_memory_packing_void_func([
Instruction::i32_const(I32(65537)),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(0)),
Instruction::memory_init(DataIdx::new(0U), MemIdx::new(0U)),
Instruction::data_drop(DataIdx::new(0U)),
])
Module::new()
.with_type_sec(type_sec)
.with_func_sec(func_sec)
.with_mem_sec(MemSec::new([memory32]))
.with_data_cnt_sec(DataCntSec::new(U32(1U)))
.with_code_sec(code_sec)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
b"abc",
),
]),
)
}
MemoryPackingMemory64Profile => {
let type_sec = TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([ValType::i64()], []))),
])
Module::new()
.with_type_sec(type_sec)
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_mem_sec(MemSec::new([MemType::new(Limits::i64(1UL, None))]))
.with_data_cnt_sec(DataCntSec::new(U32(1U)))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(payload_size)),
Instruction::memory_init(DataIdx::new(0U), MemIdx::new(0U)),
]),
),
]),
)
.with_data_sec(DataSec::new([Data::new(DataMode::passive(), zero_heavy)]))
}
MemoryPackingBoundariesProfile =>
Module::new()
.with_mem_sec(MemSec::new([memory32]))
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
zero_heavy,
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(128))]),
),
zero_heavy,
),
]),
)
.with_name_sec(
NameSec::new(
data_names=Some(
NameMap::new([NameAssoc::new(1U, Name::new("__llvm_covfun"))]),
),
),
)
MemoryPackingImportedOverlapProfile =>
Module::new()
.with_import_sec(
ImportSec::new([
Import::new(
Name::new("env"),
Name::new("memory"),
ExternType::mem(memory32),
),
]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
zero_heavy,
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(8))]),
),
b"later",
),
]),
)
_ => Module::new()
}
}
///|
pub fn gen_valid_memory_packing_profile_case_label(
profile : GenValidProfile,
) -> String? {
match profile {
MemoryPackingActiveRangesProfile => Some("memory-packing:active-ranges")
MemoryPackingActiveTrapsProfile => Some("memory-packing:active-traps")
MemoryPackingDefinedOverlapProfile => Some("memory-packing:defined-overlap")
MemoryPackingPassiveSplitsProfile => Some("memory-packing:passive-splits")
MemoryPackingSegmentOpsProfile => Some("memory-packing:segment-ops")
MemoryPackingMemory64Profile => Some("memory-packing:memory64")
MemoryPackingBoundariesProfile => Some("memory-packing:boundaries")
MemoryPackingImportedOverlapProfile =>
Some("memory-packing:imported-overlap")
_ => None
}
}
///|
fn gen_valid_heap_store_optimization_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 16,
max_imports: 0,
max_defined_funcs: 4,
max_tables: 1,
max_mems: 1,
max_globals: 2,
max_tags: 1,
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 0,
max_locals: 0,
max_body_statements: match profile {
HsoTeeProfile => 90
HsoChainProfile => 91
HsoDefaultProfile => 92
HsoSideEffectsProfile => 93
HsoDescriptorProfile => 94
HsoControlFlowProfile => 95
HsoSwapProfile => 96
HsoSharedOrderingProfile => 97
HsoBoundariesProfile => 98
_ => 90
},
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tags: true,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: profile == HsoSharedOrderingProfile,
allow_shared_memories: profile == HsoSharedOrderingProfile,
allow_memory64: false,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: false,
allow_heap_store_optimization_body_generator: true,
allow_name_custom_sections: false,
},
}
}
///|
pub fn gen_valid_heap_store_optimization_profile_case_label(
profile : GenValidProfile,
) -> String? {
match profile {
HsoTeeProfile => Some("hso:tee")
HsoChainProfile => Some("hso:chains")
HsoDefaultProfile => Some("hso:defaults")
HsoSideEffectsProfile => Some("hso:side-effects")
HsoDescriptorProfile => Some("hso:descriptors")
HsoControlFlowProfile => Some("hso:control-flow")
HsoSwapProfile => Some("hso:swaps")
HsoSharedOrderingProfile => Some("hso:shared-ordering")
HsoBoundariesProfile => Some("hso:boundaries")
_ => None
}
}
///|
fn gen_valid_heap2local_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: match profile {
Heap2LocalRefProfile => 8
_ => 6
},
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 0,
max_locals: 0,
max_body_statements: match profile {
Heap2LocalArrayProfile => 1
Heap2LocalRefProfile => 2
Heap2LocalAllProfile => 3
_ => 0
},
max_body_depth: 2,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: true,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: false,
allow_shared_memories: false,
allow_memory64: false,
allow_subtyping_topology: profile == Heap2LocalRefProfile,
allow_name_custom_sections: false,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: false,
allow_heap_store_optimization_body_generator: false,
allow_heap2local_body_generator: true,
},
}
}
///|
fn gen_valid_local_subtyping_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
let profile_depth = match profile {
LocalSubtypingStraightLineProfile => 1
LocalSubtypingStructuredProfile => 2
LocalSubtypingUnreachableTailProfile => 3
LocalSubtypingLubsProfile => 4
LocalSubtypingIterationProfile => 5
LocalSubtypingNullBottomProfile => 6
LocalSubtypingControlRefinalizeProfile => 7
_ => 1
}
GenValidConfig::{
..base,
max_type_defs: 6,
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 0,
max_locals: 0,
max_body_statements: 0,
max_body_depth: profile_depth,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: true,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: false,
allow_shared_memories: false,
allow_memory64: false,
allow_subtyping_topology: true,
allow_name_custom_sections: false,
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_coalesce_locals_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
let max_body_depth = match profile {
CoalesceLocalsStraightLineProfile => 1
CoalesceLocalsStructuredProfile => 2
CoalesceLocalsLoopCopyThroughProfile => 3
CoalesceLocalsEntryValuesProfile => 4
CoalesceLocalsCopyPreferenceProfile => 5
CoalesceLocalsTeeCopiesProfile => 6
CoalesceLocalsInterBlockProfile => 7
CoalesceLocalsUnreachableProfile => 8
CoalesceLocalsLegacyEhProfile => 9
CoalesceLocalsLargeUnusedProfile => 10
CoalesceLocalsExactTypesProfile => 11
_ => 1
}
let legacy_eh = profile == CoalesceLocalsLegacyEhProfile
GenValidConfig::{
..base,
max_type_defs: if legacy_eh {
1
} else {
0
},
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: if profile == CoalesceLocalsUnreachableProfile {
1
} else {
0
},
max_globals: 0,
max_tags: if legacy_eh {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 0,
max_locals: if profile == CoalesceLocalsLargeUnusedProfile {
64
} else {
4
},
max_body_statements: 0,
max_body_depth,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: profile == CoalesceLocalsUnreachableProfile,
allow_globals: false,
allow_tags: legacy_eh,
allow_elems: false,
allow_datas: false,
allow_ref_types: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: profile != CoalesceLocalsStraightLineProfile &&
profile != CoalesceLocalsCopyPreferenceProfile &&
profile != CoalesceLocalsTeeCopiesProfile &&
profile != CoalesceLocalsLargeUnusedProfile &&
profile != CoalesceLocalsExactTypesProfile,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: false,
allow_shared_memories: false,
allow_memory64: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
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_rume_profile_config(profile : GenValidProfile) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: if profile == RumeContinuationsDescriptorsProfile {
4
} else {
3
},
max_imports: if profile == RumeSpecialImportsProfile {
1
} else {
0
},
max_defined_funcs: if profile == RumeIndexRemapStressProfile {
6
} else {
3
},
max_tables: 1,
max_mems: 1,
max_globals: if profile == RumeIndexRemapStressProfile {
2
} else {
1
},
max_tags: 2,
max_elems: 1,
max_datas: 1,
max_params: 0,
max_results: 1,
max_locals: 0,
max_body_statements: match profile {
RumeDeadGraphProfile => 78
RumeTableTrapProfile => 79
RumeLegacyEhProfile => 80
RumeSpecialImportsProfile => 81
RumeCallableReferencesProfile => 82
RumeContinuationsDescriptorsProfile => 83
RumeIndexRemapStressProfile => 84
_ => 78
},
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: profile == RumeSpecialImportsProfile,
allow_tables: true,
allow_mems: true,
allow_globals: true,
allow_tags: true,
allow_elems: true,
allow_datas: true,
allow_ref_types: true,
allow_calls: true,
allow_call_indirect: true,
allow_tail_calls: profile == RumeSpecialImportsProfile,
allow_branch_heavy_control: true,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: false,
allow_shared_memories: false,
allow_memory64: false,
allow_subtyping_topology: profile == RumeContinuationsDescriptorsProfile,
allow_name_custom_sections: false,
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_rume_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(RumeDeadGraphProfile) ||
config == GenValidConfig::for_profile(RumeTableTrapProfile) ||
config == GenValidConfig::for_profile(RumeLegacyEhProfile) ||
config == GenValidConfig::for_profile(RumeSpecialImportsProfile) ||
config == GenValidConfig::for_profile(RumeCallableReferencesProfile) ||
config == GenValidConfig::for_profile(RumeContinuationsDescriptorsProfile) ||
config == GenValidConfig::for_profile(RumeIndexRemapStressProfile)
}
///|
pub fn gen_valid_rume_profile_case_label(
profile : GenValidProfile,
_seed : UInt64,
) -> String? {
match profile {
RumeDeadGraphProfile => Some("rume:dead-module-graph")
RumeTableTrapProfile => Some("rume:indirect-call-trap-retention")
RumeLegacyEhProfile => Some("rume:legacy-eh-remap")
RumeSpecialImportsProfile => Some("rume:special-import-liveness")
RumeCallableReferencesProfile => Some("rume:callable-reference-liveness")
RumeContinuationsDescriptorsProfile =>
Some("rume:continuation-descriptor-liveness")
RumeIndexRemapStressProfile => Some("rume:index-remap-stress")
_ => None
}
}
///|
fn gen_valid_rume_void_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [])))
}
///|
fn gen_valid_rume_dead_graph_module(seed : UInt64) -> Module {
let value = ((seed >> 8) & 0x7fUL).to_int()
let funcref = RefType::new(true, HeapType::abs(AbsHeapType::func()))
Module::new()
.with_type_sec(TypeSec::new([gen_valid_rume_void_type()]))
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U), TypeIdx::new(0U)]),
)
.with_table_sec(
TableSec::new([
Table::new(TableType::new(funcref, Limits::i32(1U, None)), None),
]),
)
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(0U))]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::i32_const(I32(value))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("root"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_elem_sec(
ElemSec::new([
Elem::new(ElemMode::declarative(), ElemKind::funcs([FuncIdx::new(2U)])),
]),
)
.with_data_sec(
DataSec::new([Data::new(DataMode::passive(), Bytes::from_array([0x41]))]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::call(FuncIdx::new(1U))]),
),
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
]),
)
}
///|
fn gen_valid_rume_table_trap_module() -> Module {
let funcref = RefType::new(true, HeapType::abs(AbsHeapType::func()))
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(SubType::comp_type(CompType::func([], [ValType::i64()]))),
gen_valid_rume_void_type(),
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(2U)]),
)
.with_table_sec(
TableSec::new([
Table::new(
TableType::new(funcref, Limits::i32(1U, None)),
Some(Expr::new([Instruction::ref_func(FuncIdx::new(0U))])),
),
]),
)
.with_elem_sec(
ElemSec::new([
Elem::new(
ElemMode::active(
TableIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
ElemKind::funcs([FuncIdx::new(1U)]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("caller"),
ExternIdx::func(FuncIdx::new(2U)),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(1))])),
Func::new(Locals::empty(), Expr::new([Instruction::unreachable_()])),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::call_indirect(TypeIdx::new(0U), TableIdx::new(0U)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_rume_legacy_eh_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_rume_void_type()]))
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U), TypeIdx::new(0U)]),
)
.with_tag_sec(
TagSec::new([TagType::new(TypeIdx::new(0U)), TagType::new(TypeIdx::new(0U))]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("root"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(
Locals::empty(),
Expr::new([
Instruction::try_(
BlockType::void_(),
Expr::new([Instruction::call(FuncIdx::new(0U))]),
[
@lib.LegacyCatch::tagged(
TagIdx::new(1U),
Expr::new([Instruction::call(FuncIdx::new(0U))]),
),
],
),
]),
),
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
]),
)
}
///|
fn gen_valid_rume_call_without_effects_module(tail : Bool) -> Module {
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_rume_void_type(),
RecType::new(SubType::comp_type(CompType::func([ValType::funcref()], []))),
]),
)
.with_import_sec(
ImportSec::new([
Import::new(
Name::from_string("binaryen-intrinsics"),
Name::from_string("call.without.effects"),
ExternType::func(TypeIdx::new(1U)),
),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U)]))
.with_elem_sec(
ElemSec::new([
Elem::new(ElemMode::declarative(), ElemKind::funcs([FuncIdx::new(1U)])),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("root"), ExternIdx::func(FuncIdx::new(2U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_func(FuncIdx::new(1U)),
if tail {
Instruction::return_call(FuncIdx::new(0U))
} else {
Instruction::call(FuncIdx::new(0U))
},
]),
),
]),
)
}
///|
fn gen_valid_rume_configure_all_module(tail : Bool) -> Module {
let array_type_idx = TypeIdx::new(1U)
let array_ref = ValType::ref_type(
RefType::new(false, HeapType::new(array_type_idx)),
)
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_rume_void_type(),
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(
StorageType::val_type(ValType::funcref()),
Mut::var_(),
),
),
),
),
RecType::new(
SubType::comp_type(
CompType::func(
[ValType::externref(), array_ref, ValType::i32(), ValType::i32()],
[],
),
),
),
]),
)
.with_import_sec(
ImportSec::new([
Import::new(
Name::from_string("wasm:js-prototypes"),
Name::from_string("configureAll"),
ExternType::func(TypeIdx::new(2U)),
),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U)]))
.with_elem_sec(
ElemSec::new([
Elem::new(ElemMode::passive(), ElemKind::funcs([FuncIdx::new(1U)])),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("root"), ExternIdx::func(FuncIdx::new(2U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::extern_())),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(1)),
Instruction::array_new_elem(array_type_idx, ElemIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(9)),
if tail {
Instruction::return_call(FuncIdx::new(0U))
} else {
Instruction::call(FuncIdx::new(0U))
},
]),
),
]),
)
}
///|
fn gen_valid_rume_special_imports_module(seed : UInt64) -> Module {
match (seed & 3UL).to_int() {
0 => gen_valid_rume_call_without_effects_module(false)
1 => gen_valid_rume_call_without_effects_module(true)
2 => gen_valid_rume_configure_all_module(false)
_ => gen_valid_rume_configure_all_module(true)
}
}
///|
fn gen_valid_rume_callable_references_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_rume_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U)]))
.with_table_sec(
TableSec::new([
Table::new(
TableType::new(
RefType::new(true, HeapType::abs(AbsHeapType::func())),
Limits::i32(1U, None),
),
Some(Expr::new([Instruction::ref_func(FuncIdx::new(0U))])),
),
]),
)
.with_elem_sec(
ElemSec::new([
Elem::new(ElemMode::declarative(), ElemKind::funcs([FuncIdx::new(0U)])),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("root"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_func_annotation_sec(
FuncAnnotationSec::new([
FuncAnnotationAssoc::new(0U, [FuncAnnotation::new("binaryen.js.called")]),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_func(FuncIdx::new(0U)),
Instruction::call_ref(TypeIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_rume_continuations_descriptors_module() -> Module {
let described_idx = TypeIdx::new(0U)
let descriptor_idx = TypeIdx::new(1U)
let func_type_idx = TypeIdx::new(2U)
let cont_type_idx = TypeIdx::new(3U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::group([
SubType::comp_type(
CompType::struct_([]),
metadata=TypeMetadata::new(descriptor=Some(descriptor_idx)),
),
SubType::comp_type(
CompType::struct_([]),
metadata=TypeMetadata::new(describes=Some(described_idx)),
),
]),
RecType::new(SubType::comp_type(CompType::func([], []))),
RecType::new(SubType::comp_type(CompType::cont(func_type_idx))),
]),
)
.with_func_sec(FuncSec::new([func_type_idx, func_type_idx]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(
ValType::ref_type(RefType::new(false, HeapType::new(described_idx))),
false,
),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::none())),
Instruction::struct_new_desc(described_idx),
]),
),
]),
)
.with_elem_sec(
ElemSec::new([
Elem::new(ElemMode::declarative(), ElemKind::funcs([FuncIdx::new(0U)])),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("root"), ExternIdx::func(FuncIdx::new(1U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_func(FuncIdx::new(0U)),
Instruction::cont_new(cont_type_idx),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_rume_index_remap_stress_module(seed : UInt64) -> Module {
let value = ((seed >> 16) & 0x7fUL).to_int()
Module::new()
.with_type_sec(TypeSec::new([gen_valid_rume_void_type()]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::i32_const(I32(1))]),
),
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::i32_const(I32(value))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("root"), ExternIdx::func(FuncIdx::new(5U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(Locals::empty(), Expr::new([Instruction::nop()])),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::call(FuncIdx::new(4U)),
Instruction::global_get(GlobalIdx::new(1U)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_rume_profile_module(ctx : GenValidContext) -> Module {
if ctx.config == GenValidConfig::for_profile(RumeTableTrapProfile) {
gen_valid_rume_table_trap_module()
} else if ctx.config == GenValidConfig::for_profile(RumeLegacyEhProfile) {
gen_valid_rume_legacy_eh_module()
} else if ctx.config == GenValidConfig::for_profile(RumeSpecialImportsProfile) {
gen_valid_rume_special_imports_module(ctx.root_seed)
} else if ctx.config ==
GenValidConfig::for_profile(RumeCallableReferencesProfile) {
gen_valid_rume_callable_references_module()
} else if ctx.config ==
GenValidConfig::for_profile(RumeContinuationsDescriptorsProfile) {
gen_valid_rume_continuations_descriptors_module()
} else if ctx.config ==
GenValidConfig::for_profile(RumeIndexRemapStressProfile) {
gen_valid_rume_index_remap_stress_module(ctx.root_seed)
} else {
gen_valid_rume_dead_graph_module(ctx.root_seed)
}
}
///|
fn gen_valid_flatten_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let profile_tag = match profile {
FlattenFunctionResultsProfile => 81
FlattenOperandsProfile => 82
FlattenBlocksProfile => 83
FlattenIfsProfile => 84
FlattenLoopsProfile => 85
FlattenTeeProfile => 86
FlattenBrProfile => 87
FlattenBrIfProfile => 88
FlattenBrTableProfile => 89
FlattenUnreachableProfile => 90
FlattenMultivalueProfile => 91
FlattenLegacyEhProfile => 92
_ => 81
}
let needs_two_types = profile == FlattenLoopsProfile ||
profile == FlattenMultivalueProfile ||
profile == FlattenLegacyEhProfile
GenValidConfig::{
..base,
max_type_defs: if needs_two_types {
2
} else {
1
},
max_imports: 0,
max_defined_funcs: if profile == FlattenFunctionResultsProfile {
2
} else {
1
},
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: if profile == FlattenLegacyEhProfile {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: if profile == FlattenLoopsProfile {
1
} else {
0
},
max_results: if profile == FlattenMultivalueProfile {
2
} else {
1
},
max_locals: if profile == FlattenTeeProfile {
1
} else {
0
},
max_body_statements: profile_tag,
max_body_depth: 6,
features: {
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: profile == FlattenLegacyEhProfile,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: true,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_const_expr_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
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_flatten_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(FlattenFunctionResultsProfile) ||
config == GenValidConfig::for_profile(FlattenOperandsProfile) ||
config == GenValidConfig::for_profile(FlattenBlocksProfile) ||
config == GenValidConfig::for_profile(FlattenIfsProfile) ||
config == GenValidConfig::for_profile(FlattenLoopsProfile) ||
config == GenValidConfig::for_profile(FlattenTeeProfile) ||
config == GenValidConfig::for_profile(FlattenBrProfile) ||
config == GenValidConfig::for_profile(FlattenBrIfProfile) ||
config == GenValidConfig::for_profile(FlattenBrTableProfile) ||
config == GenValidConfig::for_profile(FlattenUnreachableProfile) ||
config == GenValidConfig::for_profile(FlattenMultivalueProfile) ||
config == GenValidConfig::for_profile(FlattenLegacyEhProfile)
}
///|
pub fn gen_valid_flatten_profile_case_label(
profile : GenValidProfile,
_seed : UInt64,
) -> String? {
match profile {
FlattenFunctionResultsProfile => Some("flatten:function-results")
FlattenOperandsProfile => Some("flatten:ordinary-operands")
FlattenBlocksProfile => Some("flatten:block-results")
FlattenIfsProfile => Some("flatten:if-results")
FlattenLoopsProfile => Some("flatten:loop-entry-and-results")
FlattenTeeProfile => Some("flatten:local-tee")
FlattenBrProfile => Some("flatten:br-payload")
FlattenBrIfProfile => Some("flatten:br-if-payload-and-false-flow")
FlattenBrTableProfile => Some("flatten:br-table-payload")
FlattenUnreachableProfile => Some("flatten:unreachable-placeholders")
FlattenMultivalueProfile => Some("flatten:multivalue-results-and-payloads")
FlattenLegacyEhProfile => Some("flatten:legacy-try-results")
_ => None
}
}
///|
fn gen_valid_flatten_void_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [])))
}
///|
fn gen_valid_flatten_i32_result_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()])))
}
///|
fn gen_valid_flatten_run_export_sec() -> ExportSec {
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
])
}
///|
fn gen_valid_flatten_function_results_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_i32_result_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U)]))
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("implicit"),
ExternIdx::func(FuncIdx::new(0U)),
),
Export::new(
Name::from_string("explicit"),
ExternIdx::func(FuncIdx::new(1U)),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(2)),
Instruction::i32_const(I32(3)),
Instruction::i32_add(),
Instruction::i32_const(I32(4)),
Instruction::i32_mul(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(5)),
Instruction::i32_const(I32(6)),
Instruction::i32_sub(),
Instruction::return_(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_operands_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(2)),
Instruction::i32_add(),
Instruction::i32_const(I32(3)),
Instruction::i32_const(I32(4)),
Instruction::i32_sub(),
Instruction::i32_mul(),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_blocks_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::drop(),
Instruction::i32_const(I32(8)),
Instruction::i32_const(I32(9)),
Instruction::i32_add(),
]),
),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_ifs_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(2)),
Instruction::i32_lt_s(),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[
Instruction::i32_const(I32(10)),
Instruction::i32_const(I32(11)),
Instruction::i32_add(),
],
Some([
Instruction::i32_const(I32(12)),
Instruction::i32_const(I32(13)),
Instruction::i32_sub(),
]),
),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_loops_module() -> Module {
let loop_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [ValType::i32()])),
)
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type(), loop_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::loop_(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(14)),
Instruction::i32_const(I32(15)),
Instruction::i32_add(),
]),
),
Instruction::drop(),
Instruction::i32_const(I32(16)),
Instruction::loop_(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([Instruction::i32_const(I32(1)), Instruction::i32_add()]),
),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_tee_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32()]),
Expr::new([
Instruction::i32_const(I32(17)),
Instruction::i32_const(I32(18)),
Instruction::i32_add(),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::i32_const(I32(19)),
Instruction::i32_mul(),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_br_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(20)),
Instruction::br(LabelIdx::new(0U)),
Instruction::i32_const(I32(21)),
Instruction::i32_eqz(),
Instruction::drop(),
]),
),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_br_if_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(22)),
Instruction::i32_const(I32(23)),
Instruction::i32_add(),
Instruction::i32_const(I32(24)),
Instruction::i32_const(I32(25)),
Instruction::i32_lt_s(),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::drop(),
Instruction::i32_const(I32(26)),
]),
),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_br_table_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(27)),
Instruction::i32_const(I32(28)),
Instruction::i32_add(),
Instruction::i32_const(I32(2)),
Instruction::br_table([LabelIdx::new(0U)], LabelIdx::new(0U)),
Instruction::i32_const(I32(29)),
Instruction::i32_eqz(),
Instruction::drop(),
]),
),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_unreachable_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::unreachable_()]),
),
Instruction::drop(),
Instruction::i32_const(I32(0)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::unreachable_()],
Some([Instruction::i32_const(I32(30))]),
),
Instruction::drop(),
Instruction::loop_(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::unreachable_()]),
),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_multivalue_module() -> Module {
let result_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32(), ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_void_type(), result_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("plain"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("br"), ExternIdx::func(FuncIdx::new(1U))),
Export::new(Name::from_string("br_if"), ExternIdx::func(FuncIdx::new(2U))),
Export::new(
Name::from_string("br_table"),
ExternIdx::func(FuncIdx::new(3U)),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(31)),
Instruction::i64_const(I64(32L)),
]),
),
Instruction::drop(),
Instruction::drop(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(33)),
Instruction::i64_const(I64(34L)),
Instruction::br(LabelIdx::new(0U)),
Instruction::unreachable_(),
]),
),
Instruction::drop(),
Instruction::drop(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(35)),
Instruction::i64_const(I64(36L)),
Instruction::i32_const(I32(0)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::drop(),
Instruction::drop(),
Instruction::i32_const(I32(37)),
Instruction::i64_const(I64(38L)),
]),
),
Instruction::drop(),
Instruction::drop(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(39)),
Instruction::i64_const(I64(40L)),
Instruction::i32_const(I32(2)),
Instruction::br_table([LabelIdx::new(0U)], LabelIdx::new(0U)),
Instruction::i32_const(I32(41)),
Instruction::i32_eqz(),
Instruction::drop(),
]),
),
Instruction::drop(),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_flatten_legacy_eh_module() -> Module {
let tag_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(TypeSec::new([gen_valid_flatten_i32_result_type(), tag_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(1U))]))
.with_export_sec(gen_valid_flatten_run_export_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::try_(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(35)),
Instruction::i32_const(I32(36)),
Instruction::i32_add(),
]),
[
@lib.LegacyCatch::tagged(
TagIdx::new(0U),
Expr::new([Instruction::i32_const(I32(37))]),
),
],
),
]),
),
]),
)
}
///|
fn gen_valid_flatten_profile_module(config : GenValidConfig) -> Module {
if config == GenValidConfig::for_profile(FlattenOperandsProfile) {
gen_valid_flatten_operands_module()
} else if config == GenValidConfig::for_profile(FlattenBlocksProfile) {
gen_valid_flatten_blocks_module()
} else if config == GenValidConfig::for_profile(FlattenIfsProfile) {
gen_valid_flatten_ifs_module()
} else if config == GenValidConfig::for_profile(FlattenLoopsProfile) {
gen_valid_flatten_loops_module()
} else if config == GenValidConfig::for_profile(FlattenTeeProfile) {
gen_valid_flatten_tee_module()
} else if config == GenValidConfig::for_profile(FlattenBrProfile) {
gen_valid_flatten_br_module()
} else if config == GenValidConfig::for_profile(FlattenBrIfProfile) {
gen_valid_flatten_br_if_module()
} else if config == GenValidConfig::for_profile(FlattenBrTableProfile) {
gen_valid_flatten_br_table_module()
} else if config == GenValidConfig::for_profile(FlattenUnreachableProfile) {
gen_valid_flatten_unreachable_module()
} else if config == GenValidConfig::for_profile(FlattenMultivalueProfile) {
gen_valid_flatten_multivalue_module()
} else if config == GenValidConfig::for_profile(FlattenLegacyEhProfile) {
gen_valid_flatten_legacy_eh_module()
} else {
gen_valid_flatten_function_results_module()
}
}
///|
fn gen_valid_merge_blocks_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let profile_tag = match profile {
MergeBlocksStructuralProfile => 71
MergeBlocksExpressionProfile => 72
MergeBlocksEffectProfile => 73
MergeBlocksEhAtomicProfile => 74
_ => 71
}
GenValidConfig::{
..base,
max_type_defs: if profile == MergeBlocksExpressionProfile ||
profile == MergeBlocksEhAtomicProfile {
2
} else {
1
},
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: if profile == MergeBlocksExpressionProfile ||
profile == MergeBlocksEffectProfile ||
profile == MergeBlocksEhAtomicProfile {
1
} else {
0
},
max_globals: if profile == MergeBlocksEffectProfile {
1
} else {
0
},
max_tags: if profile == MergeBlocksExpressionProfile ||
profile == MergeBlocksEhAtomicProfile {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: 0,
max_results: 0,
max_locals: 0,
max_body_statements: profile_tag,
max_body_depth: 5,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: profile != MergeBlocksStructuralProfile,
allow_globals: profile == MergeBlocksEffectProfile,
allow_tags: profile == MergeBlocksExpressionProfile ||
profile == MergeBlocksEhAtomicProfile,
allow_elems: false,
allow_datas: false,
allow_ref_types: profile == MergeBlocksEhAtomicProfile,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: true,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: profile == MergeBlocksEhAtomicProfile,
allow_shared_memories: profile == MergeBlocksEhAtomicProfile,
allow_memory64: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
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_merge_blocks_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(MergeBlocksStructuralProfile) ||
config == GenValidConfig::for_profile(MergeBlocksExpressionProfile) ||
config == GenValidConfig::for_profile(MergeBlocksEffectProfile) ||
config == GenValidConfig::for_profile(MergeBlocksEhAtomicProfile)
}
///|
pub fn gen_valid_merge_blocks_profile_case_label(
profile : GenValidProfile,
_seed : UInt64,
) -> String? {
match profile {
MergeBlocksStructuralProfile => Some("merge-blocks:structural")
MergeBlocksExpressionProfile => Some("merge-blocks:expression-children")
MergeBlocksEffectProfile => Some("merge-blocks:effect-order")
MergeBlocksEhAtomicProfile => Some("merge-blocks:eh-atomic-boundaries")
_ => None
}
}
///|
fn gen_valid_merge_blocks_void_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [])))
}
///|
fn gen_valid_merge_blocks_structural_opportunity() -> Instruction {
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::i32_const(I32(7)), Instruction::drop()]),
),
]),
)
}
///|
fn gen_valid_merge_blocks_structural_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_merge_blocks_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
gen_valid_merge_blocks_structural_opportunity(),
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::i32_const(I32(8)), Instruction::drop()]),
),
]),
),
]),
),
]),
)
}
///|
fn gen_valid_merge_blocks_expression_module() -> Module {
let tag_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [])),
)
Module::new()
.with_type_sec(TypeSec::new([tag_type, gen_valid_merge_blocks_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(0U))]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
gen_valid_merge_blocks_structural_opportunity(),
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::drop(),
Instruction::i32_const(I32(9)),
]),
),
Instruction::drop(),
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(2)),
Instruction::drop(),
Instruction::i32_const(I32(1)),
]),
),
Instruction::if_(
BlockType::void_(),
[Instruction::nop()],
Some([Instruction::nop()]),
),
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(3)),
Instruction::drop(),
Instruction::i32_const(I32(0)),
]),
),
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(4)),
Instruction::drop(),
Instruction::i32_const(I32(11)),
]),
),
Instruction::i32_store(MemArg::new(2U, None, 0UL)),
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(5)),
Instruction::drop(),
Instruction::i32_const(I32(13)),
]),
),
Instruction::throw_(TagIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_merge_blocks_effect_module() -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_merge_blocks_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
gen_valid_merge_blocks_structural_opportunity(),
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(7)),
]),
),
Instruction::i32_store(MemArg::new(2U, None, 0UL)),
]),
),
]),
)
}
///|
fn gen_valid_merge_blocks_eh_atomic_module() -> Module {
let tag_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(TypeSec::new([tag_type, gen_valid_merge_blocks_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(0U))]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
gen_valid_merge_blocks_structural_opportunity(),
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::new(TagIdx::new(0U), LabelIdx::new(0U))],
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::atomic_fence(),
Instruction::i32_const(I32(0)),
Instruction::i32_atomic_load(MemArg::new(2U, None, 0UL)),
Instruction::drop(),
]),
),
]),
),
]),
),
]),
),
]),
)
}
///|
fn gen_valid_merge_blocks_profile_module(config : GenValidConfig) -> Module {
if config == GenValidConfig::for_profile(MergeBlocksExpressionProfile) {
gen_valid_merge_blocks_expression_module()
} else if config == GenValidConfig::for_profile(MergeBlocksEffectProfile) {
gen_valid_merge_blocks_effect_module()
} else if config == GenValidConfig::for_profile(MergeBlocksEhAtomicProfile) {
gen_valid_merge_blocks_eh_atomic_module()
} else {
gen_valid_merge_blocks_structural_module()
}
}
///|
fn gen_valid_code_folding_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let profile_tag = match profile {
CodeFoldingIfArmsProfile => 41
CodeFoldingBlockExitsProfile => 42
CodeFoldingReturnsProfile => 43
CodeFoldingTailCallsProfile => 44
CodeFoldingMovementProfile => 45
CodeFoldingEhProfile => 46
_ => 41
}
GenValidConfig::{
..base,
max_type_defs: if profile == CodeFoldingEhProfile {
2
} else {
1
},
max_imports: 0,
max_defined_funcs: if profile == CodeFoldingTailCallsProfile {
2
} else {
1
},
max_tables: 0,
max_mems: 0,
max_globals: 1,
max_tags: if profile == CodeFoldingEhProfile {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: 2,
max_results: 0,
max_locals: 0,
max_body_statements: profile_tag,
max_body_depth: 4,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: true,
allow_tags: profile == CodeFoldingEhProfile,
allow_elems: false,
allow_datas: false,
allow_ref_types: profile == CodeFoldingEhProfile,
allow_calls: profile == CodeFoldingTailCallsProfile,
allow_call_indirect: false,
allow_tail_calls: profile == CodeFoldingTailCallsProfile,
allow_branch_heavy_control: true,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: false,
allow_shared_memories: false,
allow_memory64: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
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_code_folding_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(CodeFoldingIfArmsProfile) ||
config == GenValidConfig::for_profile(CodeFoldingBlockExitsProfile) ||
config == GenValidConfig::for_profile(CodeFoldingReturnsProfile) ||
config == GenValidConfig::for_profile(CodeFoldingTailCallsProfile) ||
config == GenValidConfig::for_profile(CodeFoldingMovementProfile) ||
config == GenValidConfig::for_profile(CodeFoldingEhProfile)
}
///|
pub fn gen_valid_code_folding_profile_case_label(
profile : GenValidProfile,
_seed : UInt64,
) -> String? {
match profile {
CodeFoldingIfArmsProfile => Some("code-folding:if-arms")
CodeFoldingBlockExitsProfile => Some("code-folding:block-exits")
CodeFoldingReturnsProfile => Some("code-folding:returns-unreachable")
CodeFoldingTailCallsProfile => Some("code-folding:return-call")
CodeFoldingMovementProfile => Some("code-folding:internal-target-movement")
CodeFoldingEhProfile => Some("code-folding:eh-body")
_ => None
}
}
///|
fn gen_valid_code_folding_i32_void_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([ValType::i32()], [])))
}
///|
fn gen_valid_code_folding_shared_void_suffix() -> Array[Instruction] {
[
Instruction::i32_const(I32(7)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(8)),
Instruction::global_set(GlobalIdx::new(0U)),
]
}
///|
fn gen_valid_code_folding_global_sec() -> GlobalSec {
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
])
}
///|
fn gen_valid_code_folding_if_arms_module() -> Module {
let left = [Instruction::i32_const(I32(1)), Instruction::drop()]
let right = [Instruction::i32_const(I32(2)), Instruction::drop()]
for instr in gen_valid_code_folding_shared_void_suffix() {
left.push(instr)
}
for instr in gen_valid_code_folding_shared_void_suffix() {
right.push(instr)
}
Module::new()
.with_type_sec(TypeSec::new([gen_valid_code_folding_i32_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(gen_valid_code_folding_global_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), left, Some(right)),
]),
),
]),
)
}
///|
fn gen_valid_code_folding_block_exits_module() -> Module {
let branch_tail = gen_valid_code_folding_shared_void_suffix()
branch_tail.push(Instruction::br(LabelIdx::new(1U)))
let body = [
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), branch_tail, None),
]
for instr in gen_valid_code_folding_shared_void_suffix() {
body.push(instr)
}
Module::new()
.with_type_sec(TypeSec::new([gen_valid_code_folding_i32_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(gen_valid_code_folding_global_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::block(BlockType::void_(), Expr::new(body))]),
),
]),
)
}
///|
fn gen_valid_code_folding_terminal_tail(
terminal : Instruction,
) -> Array[Instruction] {
let tail = gen_valid_code_folding_shared_void_suffix()
tail.push(Instruction::i32_const(I32(9)))
tail.push(Instruction::global_set(GlobalIdx::new(0U)))
tail.push(Instruction::i32_const(I32(10)))
tail.push(Instruction::global_set(GlobalIdx::new(0U)))
tail.push(terminal)
tail
}
///|
fn gen_valid_code_folding_returns_module() -> Module {
let tail = gen_valid_code_folding_terminal_tail(Instruction::return_())
Module::new()
.with_type_sec(TypeSec::new([gen_valid_code_folding_i32_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(gen_valid_code_folding_global_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), tail, None),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), tail, None),
Instruction::i32_const(I32(99)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_code_folding_tail_calls_module() -> Module {
let target_type = gen_valid_code_folding_i32_void_type()
let caller_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32(), ValType::i32()], [])),
)
let tail = gen_valid_code_folding_shared_void_suffix()
tail.push(Instruction::i32_const(I32(9)))
tail.push(Instruction::global_set(GlobalIdx::new(0U)))
tail.push(Instruction::i32_const(I32(10)))
tail.push(Instruction::global_set(GlobalIdx::new(0U)))
tail.push(Instruction::local_get(LocalIdx::new(1U)))
tail.push(Instruction::return_call(FuncIdx::new(0U)))
Module::new()
.with_type_sec(TypeSec::new([target_type, caller_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_global_sec(gen_valid_code_folding_global_sec())
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([])),
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), tail, None),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), tail, None),
Instruction::i32_const(I32(99)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_code_folding_movement_module() -> Module {
let internal = Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(8)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_table([LabelIdx::new(0U)], LabelIdx::new(0U)),
]),
)
let tail = [
internal,
Instruction::i32_const(I32(9)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(10)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::return_(),
]
Module::new()
.with_type_sec(TypeSec::new([gen_valid_code_folding_i32_void_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(gen_valid_code_folding_global_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), tail, None),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), tail, None),
Instruction::i32_const(I32(99)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_code_folding_eh_module() -> Module {
let tag_type = RecType::new(SubType::comp_type(CompType::func([], [])))
let body_type = gen_valid_code_folding_i32_void_type()
let shared = gen_valid_code_folding_shared_void_suffix()
Module::new()
.with_type_sec(TypeSec::new([tag_type, body_type]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(0U))]))
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_global_sec(gen_valid_code_folding_global_sec())
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::new(TagIdx::new(0U), LabelIdx::new(0U))],
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), shared, Some(shared)),
]),
),
]),
),
]),
),
]),
)
}
///|
fn gen_valid_code_folding_profile_module(config : GenValidConfig) -> Module {
if config == GenValidConfig::for_profile(CodeFoldingBlockExitsProfile) {
gen_valid_code_folding_block_exits_module()
} else if config == GenValidConfig::for_profile(CodeFoldingReturnsProfile) {
gen_valid_code_folding_returns_module()
} else if config == GenValidConfig::for_profile(CodeFoldingTailCallsProfile) {
gen_valid_code_folding_tail_calls_module()
} else if config == GenValidConfig::for_profile(CodeFoldingMovementProfile) {
gen_valid_code_folding_movement_module()
} else if config == GenValidConfig::for_profile(CodeFoldingEhProfile) {
gen_valid_code_folding_eh_module()
} else {
gen_valid_code_folding_if_arms_module()
}
}
///|
fn gen_valid_merge_locals_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let profile_tag = match profile {
MergeLocalsForwardProfile => 11
MergeLocalsForwardMultipleProfile => 12
MergeLocalsPartialInfluenceProfile => 13
MergeLocalsReverseProfile => 14
MergeLocalsReverseBoundaryProfile => 15
MergeLocalsControlProfile => 16
MergeLocalsTeeProfile => 17
MergeLocalsMergeBoundaryProfile => 18
MergeLocalsTypeBoundaryProfile => 19
MergeLocalsRollbackProfile => 20
MergeLocalsReverseRollbackProfile => 21
MergeLocalsNestedCopiesProfile => 22
MergeLocalsTrivialConfusionProfile => 23
MergeLocalsUnreachableProfile => 24
MergeLocalsLegacyEhProfile => 25
_ => 11
}
GenValidConfig::{
..base,
max_type_defs: if profile == MergeLocalsTypeBoundaryProfile {
3
} else if profile == MergeLocalsLegacyEhProfile {
2
} else {
1
},
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: if profile == MergeLocalsLegacyEhProfile {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: if profile == MergeLocalsTrivialConfusionProfile {
3
} else if profile == MergeLocalsReverseProfile ||
profile == MergeLocalsReverseBoundaryProfile ||
profile == MergeLocalsReverseRollbackProfile ||
profile == MergeLocalsControlProfile ||
profile == MergeLocalsMergeBoundaryProfile ||
profile == MergeLocalsLegacyEhProfile {
1
} else {
0
},
max_results: 1,
max_locals: 2,
max_body_statements: profile_tag,
max_body_depth: if profile == MergeLocalsReverseRollbackProfile ||
profile == MergeLocalsLegacyEhProfile {
4
} else if profile == MergeLocalsControlProfile ||
profile == MergeLocalsReverseProfile ||
profile == MergeLocalsReverseBoundaryProfile ||
profile == MergeLocalsMergeBoundaryProfile ||
profile == MergeLocalsNestedCopiesProfile ||
profile == MergeLocalsTrivialConfusionProfile ||
profile == MergeLocalsUnreachableProfile {
2
} else {
1
},
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: profile == MergeLocalsLegacyEhProfile,
allow_elems: false,
allow_datas: false,
allow_ref_types: profile == MergeLocalsTypeBoundaryProfile,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: profile == MergeLocalsControlProfile ||
profile == MergeLocalsReverseRollbackProfile ||
profile == MergeLocalsLegacyEhProfile,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: false,
allow_shared_memories: false,
allow_memory64: false,
allow_subtyping_topology: profile == MergeLocalsTypeBoundaryProfile,
allow_name_custom_sections: false,
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_merge_locals_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(MergeLocalsForwardProfile) ||
config == GenValidConfig::for_profile(MergeLocalsForwardMultipleProfile) ||
config == GenValidConfig::for_profile(MergeLocalsPartialInfluenceProfile) ||
config == GenValidConfig::for_profile(MergeLocalsReverseProfile) ||
config == GenValidConfig::for_profile(MergeLocalsReverseBoundaryProfile) ||
config == GenValidConfig::for_profile(MergeLocalsControlProfile) ||
config == GenValidConfig::for_profile(MergeLocalsTeeProfile) ||
config == GenValidConfig::for_profile(MergeLocalsMergeBoundaryProfile) ||
config == GenValidConfig::for_profile(MergeLocalsTypeBoundaryProfile) ||
config == GenValidConfig::for_profile(MergeLocalsRollbackProfile) ||
config == GenValidConfig::for_profile(MergeLocalsReverseRollbackProfile) ||
config == GenValidConfig::for_profile(MergeLocalsNestedCopiesProfile) ||
config == GenValidConfig::for_profile(MergeLocalsTrivialConfusionProfile) ||
config == GenValidConfig::for_profile(MergeLocalsUnreachableProfile) ||
config == GenValidConfig::for_profile(MergeLocalsLegacyEhProfile)
}
///|
pub fn gen_valid_merge_locals_profile_case_label(
profile : GenValidProfile,
seed : UInt64,
) -> String? {
match profile {
MergeLocalsForwardProfile => Some("merge-locals:forward")
MergeLocalsForwardMultipleProfile => Some("merge-locals:forward-multiple")
MergeLocalsPartialInfluenceProfile =>
Some("merge-locals:partial-influence-\{(seed % 2UL).to_int()}")
MergeLocalsReverseProfile => Some("merge-locals:reverse")
MergeLocalsReverseBoundaryProfile =>
Some("merge-locals:reverse-boundary-\{(seed % 2UL).to_int()}")
MergeLocalsControlProfile =>
Some("merge-locals:control-\{(seed % 3UL).to_int()}")
MergeLocalsTeeProfile => Some("merge-locals:tee")
MergeLocalsMergeBoundaryProfile => Some("merge-locals:merge-boundary")
MergeLocalsTypeBoundaryProfile => Some("merge-locals:type-boundary")
MergeLocalsRollbackProfile => Some("merge-locals:rollback")
MergeLocalsReverseRollbackProfile =>
Some("merge-locals:reverse-rollback-\{(seed % 3UL).to_int()}")
MergeLocalsNestedCopiesProfile =>
Some("merge-locals:nested-copies-\{(seed % 2UL).to_int()}")
MergeLocalsTrivialConfusionProfile => Some("merge-locals:trivial-confusion")
MergeLocalsUnreachableProfile => Some("merge-locals:unreachable")
MergeLocalsLegacyEhProfile =>
match (seed % 4UL).to_int() {
0 => Some("merge-locals:legacy-eh-protected")
1 => Some("merge-locals:legacy-eh-catch")
2 => Some("merge-locals:legacy-eh-catch-all")
_ => Some("merge-locals:legacy-eh-delegate")
}
_ => None
}
}
///|
fn gen_valid_remove_unused_brs_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let mut config = GenValidConfig::{
..base,
max_type_defs: 6,
max_imports: 0,
max_defined_funcs: 2,
max_tables: 0,
max_mems: 0,
max_globals: 1,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 2,
max_results: 1,
max_locals: 6,
max_body_statements: 10,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: true,
allow_typed_body_generator: true,
allow_name_custom_sections: false,
},
}
match profile {
RemoveUnusedBrsSwitchProfile =>
config = GenValidConfig::{
..config,
max_locals: 8,
max_body_statements: 14,
max_body_depth: 4,
}
RemoveUnusedBrsGcProfile =>
config = GenValidConfig::{
..config,
max_type_defs: 10,
max_body_statements: 12,
features: GenValidFeatureToggles::{
..config.features,
allow_ref_types: true,
allow_subtyping_topology: true,
},
}
RemoveUnusedBrsCleanupProfile =>
config = GenValidConfig::{
..config,
max_defined_funcs: 3,
max_locals: 8,
max_body_statements: 14,
}
RemoveUnusedBrsConstantBrIfProfile
| RemoveUnusedBrsSingleTargetBrTableProfile
| RemoveUnusedBrsMultiFunctionProfile
| RemoveUnusedBrsResultRefinalizeProfile
| RemoveUnusedBrsMultivalueDropProfile
| RemoveUnusedBrsWrapperCleanupProfile
| RemoveUnusedBrsSelectifyProfile
| RemoveUnusedBrsTailFlowProfile
| RemoveUnusedBrsOneArmIfProfile
| RemoveUnusedBrsLoopProfile
| RemoveUnusedBrsSinkBlocksProfile
| RemoveUnusedBrsEhProfile
| RemoveUnusedBrsJumpThreadProfile
| RemoveUnusedBrsTablifyProfile
| RemoveUnusedBrsOptimizeSetIfProfile
| RemoveUnusedBrsRestructureIfProfile
| RemoveUnusedBrsAdjacentBranchProfile
| RemoveUnusedBrsWinBoundaryProfile =>
config = GenValidConfig::{
..config,
max_defined_funcs: if profile == RemoveUnusedBrsMultiFunctionProfile {
3
} else {
2
},
max_tags: if profile == RemoveUnusedBrsEhProfile {
1
} else {
0
},
max_results: 2,
max_locals: 8,
max_body_statements: 0,
max_body_depth: match profile {
RemoveUnusedBrsConstantBrIfProfile => 11
RemoveUnusedBrsSingleTargetBrTableProfile => 12
RemoveUnusedBrsMultiFunctionProfile => 13
RemoveUnusedBrsResultRefinalizeProfile => 14
RemoveUnusedBrsMultivalueDropProfile => 15
RemoveUnusedBrsWrapperCleanupProfile => 16
RemoveUnusedBrsSelectifyProfile => 17
RemoveUnusedBrsWinBoundaryProfile => 18
RemoveUnusedBrsTailFlowProfile => 19
RemoveUnusedBrsOneArmIfProfile => 20
RemoveUnusedBrsLoopProfile => 21
RemoveUnusedBrsSinkBlocksProfile => 22
RemoveUnusedBrsEhProfile => 23
RemoveUnusedBrsJumpThreadProfile => 24
RemoveUnusedBrsTablifyProfile => 25
RemoveUnusedBrsOptimizeSetIfProfile => 26
RemoveUnusedBrsRestructureIfProfile => 27
RemoveUnusedBrsAdjacentBranchProfile => 28
_ => 10
},
features: GenValidFeatureToggles::{
..config.features,
allow_tags: profile == RemoveUnusedBrsEhProfile,
allow_ref_types: profile == RemoveUnusedBrsResultRefinalizeProfile ||
profile == RemoveUnusedBrsSelectifyProfile ||
profile == RemoveUnusedBrsConstantBrIfProfile ||
profile == RemoveUnusedBrsSingleTargetBrTableProfile,
allow_subtyping_topology: profile ==
RemoveUnusedBrsResultRefinalizeProfile ||
profile == RemoveUnusedBrsSelectifyProfile,
allow_typed_body_generator: false,
},
}
_ => ()
}
config
}
///|
fn gen_valid_duplicate_import_elimination_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let module_code = profile == DuplicateImportEliminationModuleCodeProfile
let legacy_eh = profile == DuplicateImportEliminationLegacyEhProfile
let nonfunction = profile == DuplicateImportEliminationNonfunctionProfile
GenValidConfig::{
..base,
max_type_defs: 4,
max_imports: if nonfunction {
8
} else {
5
},
max_defined_funcs: 1,
max_tables: if module_code {
1
} else {
0
},
max_mems: 0,
max_globals: if module_code {
1
} else {
0
},
max_tags: if legacy_eh {
1
} else {
0
},
max_elems: if module_code {
3
} else if nonfunction {
0
} else {
1
},
max_datas: 0,
max_params: 1,
max_results: 0,
max_locals: 0,
max_body_statements: if legacy_eh {
16
} else {
12
},
max_body_depth: if legacy_eh {
4
} else {
3
},
features: GenValidFeatureToggles::{
..base.features,
allow_imports: true,
allow_tables: module_code || nonfunction,
allow_mems: nonfunction,
allow_globals: module_code || nonfunction,
allow_tags: legacy_eh || nonfunction,
allow_start: !nonfunction,
allow_elems: !nonfunction,
allow_datas: false,
allow_ref_types: !nonfunction,
allow_calls: !nonfunction,
allow_call_indirect: false,
allow_tail_calls: profile == DuplicateImportEliminationFunctionsProfile,
allow_branch_heavy_control: profile ==
DuplicateImportEliminationFunctionsProfile ||
legacy_eh,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: false,
allow_shared_memories: false,
allow_memory64: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: false,
allow_heap_store_optimization_body_generator: false,
allow_heap2local_body_generator: false,
},
}
}
///|
pub fn gen_valid_duplicate_import_elimination_profile_case_label(
profile : GenValidProfile,
seed : UInt64,
) -> String? {
match profile {
DuplicateImportEliminationFunctionsProfile =>
Some("duplicate-import-elimination:body-references")
DuplicateImportEliminationIdentityProfile =>
match (seed % 5UL).to_int() {
0 => Some("duplicate-import-elimination:identity-same-type")
1 => Some("duplicate-import-elimination:identity-representative-reset")
2 => Some("duplicate-import-elimination:identity-different-module")
3 => Some("duplicate-import-elimination:identity-different-base")
_ =>
Some("duplicate-import-elimination:identity-equal-structural-types")
}
DuplicateImportEliminationModuleCodeProfile =>
Some("duplicate-import-elimination:module-code-references")
DuplicateImportEliminationLegacyEhProfile =>
match (seed % 5UL).to_int() {
0 => Some("duplicate-import-elimination:legacy-eh-protected")
1 => Some("duplicate-import-elimination:legacy-eh-typed-catch")
2 => Some("duplicate-import-elimination:legacy-eh-catch-all")
3 => Some("duplicate-import-elimination:legacy-eh-delegate")
_ => Some("duplicate-import-elimination:try-table-protected")
}
DuplicateImportEliminationNonfunctionProfile =>
Some("duplicate-import-elimination:nonfunction-negative")
_ => None
}
}
///|
fn gen_valid_is_duplicate_import_elimination_profile_config(
config : GenValidConfig,
) -> Bool {
config ==
GenValidConfig::for_profile(DuplicateImportEliminationFunctionsProfile) ||
config ==
GenValidConfig::for_profile(DuplicateImportEliminationIdentityProfile) ||
config ==
GenValidConfig::for_profile(DuplicateImportEliminationModuleCodeProfile) ||
config ==
GenValidConfig::for_profile(DuplicateImportEliminationLegacyEhProfile) ||
config ==
GenValidConfig::for_profile(DuplicateImportEliminationNonfunctionProfile)
}
///|
pub fn gen_valid_ssa_full_profile_case_label(
profile : GenValidProfile,
) -> String? {
match profile {
SsaFreshSetProfile => Some("ssa:fresh-set-and-retarget")
SsaFreshTeeProfile => Some("ssa:fresh-tee-and-retarget")
SsaParamEntryProfile => Some("ssa:single-param-entry")
SsaDefaultNumericProfile => Some("ssa:single-default-numeric")
SsaDefaultRefProfile => Some("ssa:single-default-ref-refinalize")
SsaUnreachableProfile => Some("ssa:unreachable-get-noop")
SsaMergeExplicitProfile => Some("ssa:merge-explicit-writes")
SsaMergeParamEntryProfile => Some("ssa:merge-param-entry-prepend")
SsaMergeDefaultEntryProfile => Some("ssa:merge-default-entry-no-prepend")
SsaMergeSharedSetsProfile => Some("ssa:merge-shared-sets-nested-tees")
SsaLoopProfile => Some("ssa:loop-backedge-merge")
SsaBranchProfile => Some("ssa:branch-target-merges")
SsaTypedControlProfile => Some("ssa:typed-control-local-flow")
SsaNestedValueProfile => Some("ssa:nested-value-block-local-flow")
SsaEhProfile => Some("ssa:exceptional-local-flow")
_ => None
}
}
///|
fn gen_valid_ssa_full_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: if profile == SsaDefaultRefProfile {
8
} else {
4
},
max_imports: 0,
max_defined_funcs: 1,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: if profile == SsaEhProfile {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: if profile == SsaEhProfile {
0
} else {
2
},
max_results: 0,
max_locals: 12,
max_body_statements: match profile {
SsaFreshSetProfile => 101
SsaFreshTeeProfile => 102
SsaParamEntryProfile => 103
SsaDefaultNumericProfile => 104
SsaDefaultRefProfile => 105
SsaUnreachableProfile => 106
SsaMergeExplicitProfile => 107
SsaMergeParamEntryProfile => 108
SsaMergeDefaultEntryProfile => 109
SsaMergeSharedSetsProfile => 110
SsaLoopProfile => 111
SsaBranchProfile => 112
SsaTypedControlProfile => 113
SsaNestedValueProfile => 114
SsaEhProfile => 115
_ => 100
},
max_body_depth: 6,
features: GenValidFeatureToggles::{
..base.features,
allow_branch_heavy_control: true,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: true,
allow_calls: false,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: profile == SsaEhProfile,
allow_v128: profile == SsaDefaultNumericProfile,
allow_relaxed_simd: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_memory64: false,
allow_atomics: false,
allow_shared_memories: false,
allow_subtyping_topology: false,
allow_ref_types: profile == SsaDefaultRefProfile,
allow_name_custom_sections: false,
},
}
}
///|
fn gen_valid_ssa_nomerge_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let max_locals = match profile {
SsaNomergeParityProfile => 8
SsaNomergeSmokeProfile => 10
_ => 12
}
GenValidConfig::{
..base,
max_type_defs: 6,
max_defined_funcs: 8,
max_params: 4,
max_results: 2,
max_locals,
max_body_statements: 24,
max_body_depth: 5,
features: GenValidFeatureToggles::{
..base.features,
allow_branch_heavy_control: true,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: true,
allow_calls: false,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_memory64: false,
allow_atomics: false,
allow_shared_memories: false,
allow_subtyping_topology: false,
allow_ref_types: false,
allow_name_custom_sections: false,
},
}
}
///|
fn gen_valid_slns_profile_config(profile : GenValidProfile) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let common = GenValidFeatureToggles::{
..base.features,
allow_branch_heavy_control: true,
allow_typed_body_generator: false,
allow_ssa_nomerge_body_generator: true,
allow_name_custom_sections: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_atomics: false,
allow_shared_memories: false,
allow_memory64: false,
allow_tail_calls: false,
allow_call_indirect: false,
allow_subtyping_topology: false,
}
match profile {
SimplifyLocalsLocalTrafficProfile =>
GenValidConfig::{
..base,
max_type_defs: 2,
max_imports: 0,
max_defined_funcs: 3,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 3,
max_results: 0,
max_locals: 9,
max_body_statements: 20,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..common,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_calls: false,
allow_ref_types: false,
allow_branch_heavy_control: false,
},
}
SimplifyLocalsStructureResultProfile =>
GenValidConfig::{
..base,
max_type_defs: 3,
max_imports: 0,
max_defined_funcs: 4,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 3,
max_results: 0,
max_locals: 12,
max_body_statements: 30,
max_body_depth: 6,
features: GenValidFeatureToggles::{
..common,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_calls: false,
allow_ref_types: false,
allow_branch_heavy_control: true,
},
}
SimplifyLocalsFlatParentProfile =>
GenValidConfig::{
..base,
max_type_defs: 2,
max_imports: 0,
max_defined_funcs: 3,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 2,
max_results: 0,
max_locals: 7,
max_body_statements: 16,
max_body_depth: 3,
features: GenValidFeatureToggles::{
..common,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_calls: false,
allow_ref_types: false,
allow_branch_heavy_control: false,
},
}
SimplifyLocalsEffectOrderProfile =>
GenValidConfig::{
..base,
max_type_defs: 7,
max_imports: 2,
max_defined_funcs: 5,
max_tables: 0,
max_mems: 1,
max_globals: 2,
max_tags: 0,
max_elems: 0,
max_datas: 1,
max_params: 3,
max_results: 0,
max_locals: 12,
max_body_statements: 32,
max_body_depth: 5,
features: GenValidFeatureToggles::{
..common,
allow_imports: true,
allow_tables: false,
allow_mems: true,
allow_globals: true,
allow_tags: false,
allow_calls: false,
allow_ref_types: false,
},
}
SimplifyLocalsStressProfile =>
GenValidConfig::{
..base,
max_type_defs: 8,
max_imports: 2,
max_defined_funcs: 6,
max_tables: 0,
max_mems: 1,
max_globals: 3,
max_tags: 0,
max_elems: 0,
max_datas: 2,
max_params: 4,
max_results: 0,
max_locals: 16,
max_body_statements: 48,
max_body_depth: 7,
features: GenValidFeatureToggles::{
..common,
allow_imports: true,
allow_tables: false,
allow_mems: true,
allow_globals: true,
allow_tags: false,
allow_calls: false,
allow_ref_types: false,
allow_branch_heavy_control: true,
},
}
SimplifyLocalsNostructureStraightLineProfile =>
GenValidConfig::{
..base,
max_type_defs: 2,
max_imports: 0,
max_defined_funcs: 3,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 2,
max_results: 0,
max_locals: 8,
max_body_statements: 18,
max_body_depth: 2,
features: GenValidFeatureToggles::{
..common,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_calls: false,
allow_ref_types: false,
allow_branch_heavy_control: false,
},
}
SimplifyLocalsNostructureTeeControlProfile =>
GenValidConfig::{
..base,
max_type_defs: 3,
max_imports: 0,
max_defined_funcs: 3,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: 2,
max_results: 0,
max_locals: 10,
max_body_statements: 22,
max_body_depth: 4,
features: GenValidFeatureToggles::{
..common,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_calls: false,
allow_ref_types: false,
},
}
SimplifyLocalsNostructureEffectOrderProfile =>
GenValidConfig::{
..base,
max_type_defs: 6,
max_imports: 2,
max_defined_funcs: 4,
max_tables: 0,
max_mems: 1,
max_globals: 2,
max_tags: 0,
max_elems: 0,
max_datas: 1,
max_params: 2,
max_results: 0,
max_locals: 10,
max_body_statements: 28,
max_body_depth: 4,
features: GenValidFeatureToggles::{
..common,
allow_imports: true,
allow_tables: false,
allow_mems: true,
allow_globals: true,
allow_tags: false,
allow_calls: false,
allow_ref_types: false,
},
}
_ =>
gen_valid_slns_profile_config(
SimplifyLocalsNostructureStraightLineProfile,
)
}
}
///|
pub fn GenValidConfig::profile(name : String) -> Result[GenValidConfig, String] {
match gen_valid_profile_by_name(name) {
Ok(profile) => Ok(GenValidConfig::for_profile(profile))
Err(msg) => Err(msg)
}
}
///|
fn gen_valid_is_topology_heavy_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(TopologyHeavyProfile)
}
///|
fn gen_valid_is_control_heavy_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(ControlHeavyProfile)
}
///|
fn gen_valid_is_ssa_nomerge_family_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(SsaNomergeCoverageProfile) ||
config == GenValidConfig::for_profile(SsaNomergeSmokeProfile) ||
config == GenValidConfig::for_profile(SsaNomergeParityProfile) ||
config == GenValidConfig::for_profile(SsaNomergeStressProfile)
}
///|
fn gen_valid_is_ssa_full_family_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(SsaFreshSetProfile) ||
config == GenValidConfig::for_profile(SsaFreshTeeProfile) ||
config == GenValidConfig::for_profile(SsaParamEntryProfile) ||
config == GenValidConfig::for_profile(SsaDefaultNumericProfile) ||
config == GenValidConfig::for_profile(SsaDefaultRefProfile) ||
config == GenValidConfig::for_profile(SsaUnreachableProfile) ||
config == GenValidConfig::for_profile(SsaMergeExplicitProfile) ||
config == GenValidConfig::for_profile(SsaMergeParamEntryProfile) ||
config == GenValidConfig::for_profile(SsaMergeDefaultEntryProfile) ||
config == GenValidConfig::for_profile(SsaMergeSharedSetsProfile) ||
config == GenValidConfig::for_profile(SsaLoopProfile) ||
config == GenValidConfig::for_profile(SsaBranchProfile) ||
config == GenValidConfig::for_profile(SsaTypedControlProfile) ||
config == GenValidConfig::for_profile(SsaNestedValueProfile) ||
config == GenValidConfig::for_profile(SsaEhProfile)
}
///|
fn gen_valid_is_remove_unused_brs_focused_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(RemoveUnusedBrsConstantBrIfProfile) ||
config ==
GenValidConfig::for_profile(RemoveUnusedBrsSingleTargetBrTableProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsMultiFunctionProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsResultRefinalizeProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsMultivalueDropProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsWrapperCleanupProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsSelectifyProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsTailFlowProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsOneArmIfProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsLoopProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsSinkBlocksProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsEhProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsJumpThreadProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsTablifyProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsOptimizeSetIfProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsRestructureIfProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsAdjacentBranchProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsWinBoundaryProfile)
}
///|
fn gen_valid_is_remove_unused_brs_family_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(RemoveUnusedBrsControlProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsSwitchProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsGcProfile) ||
config == GenValidConfig::for_profile(RemoveUnusedBrsCleanupProfile) ||
gen_valid_is_remove_unused_brs_focused_config(config)
}
///|
fn gen_valid_is_local_subtyping_family_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(LocalSubtypingStraightLineProfile) ||
config == GenValidConfig::for_profile(LocalSubtypingStructuredProfile) ||
config == GenValidConfig::for_profile(LocalSubtypingUnreachableTailProfile) ||
config == GenValidConfig::for_profile(LocalSubtypingLubsProfile) ||
config == GenValidConfig::for_profile(LocalSubtypingIterationProfile) ||
config == GenValidConfig::for_profile(LocalSubtypingNullBottomProfile) ||
config == GenValidConfig::for_profile(LocalSubtypingControlRefinalizeProfile)
}
///|
fn gen_valid_is_coalesce_locals_family_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(CoalesceLocalsStraightLineProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsStructuredProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsLoopCopyThroughProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsEntryValuesProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsCopyPreferenceProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsTeeCopiesProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsInterBlockProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsUnreachableProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsLegacyEhProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsLargeUnusedProfile) ||
config == GenValidConfig::for_profile(CoalesceLocalsExactTypesProfile)
}
///|
fn gen_valid_is_optimize_casts_family_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(OptimizeCastsLaterReuseProfile) ||
config == GenValidConfig::for_profile(OptimizeCastsEarlyMotionProfile) ||
config == GenValidConfig::for_profile(OptimizeCastsBarriersProfile) ||
config == GenValidConfig::for_profile(OptimizeCastsBestCastProfile) ||
config == GenValidConfig::for_profile(OptimizeCastsRefAsProfile) ||
config == GenValidConfig::for_profile(OptimizeCastsStaticFoldsProfile) ||
config == GenValidConfig::for_profile(OptimizeCastsNeighborhoodProfile)
}
///|
fn gen_valid_is_ssa_nomerge_smoke_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(SsaNomergeSmokeProfile)
}
///|
fn gen_valid_is_ssa_nomerge_parity_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(SsaNomergeParityProfile)
}
///|
fn gen_valid_is_oi_trigger_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(PassOiDefaultScalarProfile) ||
config == GenValidConfig::for_profile(PassOiLocalFactsProfile) ||
config == GenValidConfig::for_profile(PassOiCallRefProfile) ||
config == GenValidConfig::for_profile(PassOiBooleanSelectProfile) ||
config == GenValidConfig::for_profile(PassOiRefGcProfile) ||
config == GenValidConfig::for_profile(PassOiGcAggregateProfile) ||
config == GenValidConfig::for_profile(PassOiDescriptorGcProfile) ||
config == GenValidConfig::for_profile(PassOiMemoryBulkProfile) ||
config == GenValidConfig::for_profile(PassOiTupleProfile)
}
///|
pub fn default_gen_valid_config() -> GenValidConfig {
GenValidConfig::natural_default()
}
///|
pub struct GenValidFeatureFacts {
mode : GenValidMode
has_imports : Bool
has_func_exports : Bool
has_table_exports : Bool
has_mem_exports : Bool
has_global_exports : Bool
has_tag_exports : Bool
has_start : Bool
lacks_start : Bool
has_tables : Bool
has_mems : Bool
has_globals : Bool
has_tags : Bool
has_elems : Bool
has_datas : Bool
has_data_count : Bool
uses_ref_types : Bool
uses_v128 : Bool
has_call : Bool
has_call_indirect : Bool
has_branch_heavy_control : Bool
has_payload_control_flow : Bool
has_multivalue_control_flow : Bool
has_numeric_full_ops : Bool
has_br_table : Bool
has_standalone_unreachable : Bool
has_local_tee : Bool
has_typed_select : Bool
has_tail_calls : Bool
has_grouped_local_decls : Bool
has_mixed_local_decl_types : Bool
has_high_local_indices : Bool
has_unused_locals : Bool
has_write_only_locals : Bool
has_zero_local_funcs : Bool
has_multi_param_result_arities : Bool
has_empty_body_funcs : Bool
has_unreachable_result_bodies : Bool
has_local_name_entries : Bool
has_scalar_memory_widths : Bool
has_nonzero_memarg : Bool
has_memory_limit_variants : Bool
has_table_limit_variants : Bool
has_const_expr_variants : Bool
has_basic_ref_instructions : Bool
has_i31_extern_conversions : Bool
has_simd_phase1 : Bool
has_simd_phase2 : Bool
has_simd_phase3 : Bool
has_descriptors : Bool
has_continuations : Bool
has_waitqueues : Bool
has_atomics : Bool
has_array_memory : Bool
has_gc_constructors : Bool
has_gc_accessors : Bool
has_string_ops : Bool
has_exception_try_table_matrix : Bool
has_subtyping_topology : Bool
has_rich_gc_field_plans : Bool
has_import_export_topology : Bool
has_element_segment_range : Bool
has_data_segment_range : Bool
has_name_custom_sections : Bool
has_gc_exception_combo : Bool
has_gc_tail_call_combo : Bool
has_shared_memory_atomics : Bool
has_imports_start_exports : Bool
has_semantic_effects : Bool
has_import_event_channel : Bool
has_trap_frontier : Bool
has_resource_observation : Bool
has_poisoned_dead_code : Bool
has_ssa_straight_line_local_chain : Bool
has_ssa_already_ssa_local : Bool
has_ssa_multi_def_same_local : Bool
has_ssa_param_entry_read : Bool
has_ssa_local_tee_def_use : Bool
has_ssa_tee_freshen_candidate : Bool
has_ssa_tee_merge_feeding_candidate : Bool
has_ssa_tee_child_expression : Bool
has_ssa_param_write : Bool
has_ssa_dead_local_set : Bool
has_ssa_dead_local_tee : Bool
has_ssa_if_join_phi_candidate : Bool
has_ssa_loop_backedge_phi_candidate : Bool
has_ssa_br_table_phi_candidate : Bool
has_ssa_parallel_copy_candidate : Bool
has_ssa_parallel_copy_cycle_candidate : Bool
has_ssa_default_local_merge : Bool
has_ssa_one_arm_default_merge : Bool
has_ssa_one_arm_param_merge : Bool
has_ssa_both_arm_local_merge : Bool
has_ssa_loop_carried_local_merge : Bool
has_ssa_mixed_fresh_canonical_writes : Bool
has_ssa_unreachable_local_carrier : Bool
has_ssa_dropped_increment_guard_shape : Bool
has_ssa_dropped_increment_reversed_boundary : Bool
has_ssa_exceptional_fail_closed_shape : Bool
has_ssa_typed_loop_param_fail_closed_shape : Bool
has_ssa_nested_cfg_fail_closed_shape : Bool
has_ssa_nested_result_if_supported_shape : Bool
has_ssa_nested_result_if_condition_write : Bool
has_ssa_nested_result_if_condition_value_block : Bool
has_ssa_nested_result_if_arm_value_block : Bool
has_ssa_nested_result_if_mixed_arm_value_block : Bool
has_ssa_nested_result_if_scalar_result : Bool
has_ssa_structured_early_return_local : Bool
has_ssa_block_branch_merge_copy : Bool
has_ssa_block_br_if_merge_copy : Bool
has_ssa_structured_param_merge : Bool
has_ssa_branch_local_not_read_later : Bool
has_ssa_default_local_read_after_branchy_control : Bool
has_ssa_dropped_unreachable_debris_before_hard_unreachable : Bool
has_ssa_canonical_body_local_next_read : Bool
has_ssa_immediate_block_exit_canonical_set_br : Bool
has_ssa_enclosing_label_copy_before_exit : Bool
has_ssa_branch_block_alias_copy : Bool
has_ssa_nested_enclosing_label_copy : Bool
has_ssa_parallel_branch_carrier_copy : Bool
has_ssa_tee_branch_carrier_copy : Bool
has_ssa_void_br_table_canonical_copies : Bool
has_ssa_branch_operand_local_boundary : Bool
has_ssa_nested_loop_target_boundary : Bool
has_ssa_large_structured_local_mix : Bool
exact_opcode_counts : GenValidExactOpcodeCounts
} derive(Eq, Debug)
///|
pub struct GenValidGenerated {
wasm_module : Module
config : GenValidConfig
config_label : String
attempts : Int32
facts : GenValidFeatureFacts
} derive(Eq, Debug)
///|
pub struct GenValidModuleGenerated {
wasm_module : Module
config : GenValidConfig
config_label : String
attempts : Int32
} derive(Eq, Debug)
///|
pub enum GenValidBudgetStop {
InstructionCountBudgetExceeded
ExpressionDepthBudgetExceeded
ModuleByteSizeBudgetExceeded
RecGroupSizeBudgetExceeded
SectionCountBudgetExceeded
SegmentPayloadSizeBudgetExceeded
} derive(Eq, Debug)
///|
pub struct GenValidFailure {
last_candidate : Module
config : GenValidConfig
config_label : String
attempts : Int32
validation_error_message : String
budget_stop : GenValidBudgetStop?
} derive(Eq, Debug)
///|
pub fn gen_valid_config_label(config : GenValidConfig) -> String {
if config == GenValidConfig::binaryen_oracle_coverage_forced_default() {
"binaryen-oracle-coverage-forced"
} else if config == GenValidConfig::portable_coverage_forced_default() {
"portable-coverage-forced"
} else if config == GenValidConfig::coverage_forced_default() {
"coverage-forced"
} else if config == GenValidConfig::natural_default() {
"natural"
} else {
for profile in gen_valid_profiles() {
if config == GenValidConfig::for_profile(profile) {
return gen_valid_profile_name(profile)
}
}
match config.mode {
Natural => "custom-natural"
CoverageForced => "custom-coverage-forced"
}
}
}
///|
pub struct GenValidFeatureStats {
mode : GenValidMode
modules : Int32
imports : Int32
func_exports : Int32
table_exports : Int32
mem_exports : Int32
global_exports : Int32
tag_exports : Int32
starts : Int32
lacks_start : Int32
tables : Int32
mems : Int32
globals : Int32
tags : Int32
elems : Int32
datas : Int32
data_count : Int32
ref_types : Int32
v128 : Int32
calls : Int32
call_indirect : Int32
branch_heavy_control : Int32
payload_control_flow : Int32
multivalue_control_flow : Int32
numeric_full_ops : Int32
br_table : Int32
standalone_unreachable : Int32
local_tee : Int32
typed_select : Int32
tail_calls : Int32
high_local_indices : Int32
unused_locals : Int32
write_only_locals : Int32
zero_local_funcs : Int32
multi_param_result_arities : Int32
empty_body_funcs : Int32
unreachable_result_bodies : Int32
local_name_entries : Int32
scalar_memory_widths : Int32
nonzero_memarg : Int32
memory_limit_variants : Int32
table_limit_variants : Int32
const_expr_variants : Int32
basic_ref_instructions : Int32
i31_extern_conversions : Int32
simd_phase1 : Int32
simd_phase2 : Int32
simd_phase3 : Int32
descriptors : Int32
continuations : Int32
waitqueues : Int32
atomics : Int32
array_memory : Int32
gc_constructors : Int32
gc_accessors : Int32
string_ops : Int32
exception_try_table_matrix : Int32
subtyping_topology : Int32
rich_gc_field_plans : Int32
import_export_topology : Int32
element_segment_range : Int32
data_segment_range : Int32
name_custom_sections : Int32
gc_exception_combo : Int32
gc_tail_call_combo : Int32
shared_memory_atomics : Int32
imports_start_exports : Int32
semantic_effects : Int32
import_event_channel : Int32
trap_frontier : Int32
resource_observation : Int32
poisoned_dead_code : Int32
ssa_straight_line_local_chain : Int32
ssa_already_ssa_local : Int32
ssa_multi_def_same_local : Int32
ssa_param_entry_read : Int32
ssa_local_tee_def_use : Int32
ssa_tee_freshen_candidate : Int32
ssa_tee_merge_feeding_candidate : Int32
ssa_tee_child_expression : Int32
ssa_param_write : Int32
ssa_dead_local_set : Int32
ssa_dead_local_tee : Int32
ssa_if_join_phi_candidate : Int32
ssa_loop_backedge_phi_candidate : Int32
ssa_br_table_phi_candidate : Int32
ssa_parallel_copy_candidate : Int32
ssa_parallel_copy_cycle_candidate : Int32
ssa_default_local_merge : Int32
ssa_one_arm_default_merge : Int32
ssa_one_arm_param_merge : Int32
ssa_both_arm_local_merge : Int32
ssa_loop_carried_local_merge : Int32
ssa_mixed_fresh_canonical_writes : Int32
ssa_unreachable_local_carrier : Int32
ssa_dropped_increment_guard_shape : Int32
ssa_dropped_increment_reversed_boundary : Int32
ssa_exceptional_fail_closed_shape : Int32
ssa_typed_loop_param_fail_closed_shape : Int32
ssa_nested_cfg_fail_closed_shape : Int32
ssa_nested_result_if_supported_shape : Int32
ssa_nested_result_if_condition_write : Int32
ssa_nested_result_if_condition_value_block : Int32
ssa_nested_result_if_arm_value_block : Int32
ssa_nested_result_if_mixed_arm_value_block : Int32
ssa_nested_result_if_scalar_result : Int32
ssa_structured_early_return_local : Int32
ssa_block_branch_merge_copy : Int32
ssa_block_br_if_merge_copy : Int32
ssa_structured_param_merge : Int32
ssa_branch_local_not_read_later : Int32
ssa_default_local_read_after_branchy_control : Int32
ssa_dropped_unreachable_debris_before_hard_unreachable : Int32
ssa_canonical_body_local_next_read : Int32
ssa_immediate_block_exit_canonical_set_br : Int32
ssa_enclosing_label_copy_before_exit : Int32
ssa_branch_block_alias_copy : Int32
ssa_nested_enclosing_label_copy : Int32
ssa_parallel_branch_carrier_copy : Int32
ssa_tee_branch_carrier_copy : Int32
ssa_void_br_table_canonical_copies : Int32
ssa_branch_operand_local_boundary : Int32
ssa_nested_loop_target_boundary : Int32
ssa_large_structured_local_mix : Int32
exact_opcode_counts : GenValidExactOpcodeCounts
} derive(Eq, Debug)
///|
pub impl Show for GenValidFeatureStats with fn output(self, logger) {
logger.write_string("GenValidFeatureStats {mode: ")
self.mode.output(logger)
logger.write_string(", modules: ")
self.modules.output(logger)
logger.write_string(", imports: ")
self.imports.output(logger)
logger.write_string(", func_exports: ")
self.func_exports.output(logger)
logger.write_string(", table_exports: ")
self.table_exports.output(logger)
logger.write_string(", mem_exports: ")
self.mem_exports.output(logger)
logger.write_string(", global_exports: ")
self.global_exports.output(logger)
logger.write_string(", tag_exports: ")
self.tag_exports.output(logger)
logger.write_string(", starts: ")
self.starts.output(logger)
logger.write_string(", lacks_start: ")
self.lacks_start.output(logger)
logger.write_string(", tables: ")
self.tables.output(logger)
logger.write_string(", mems: ")
self.mems.output(logger)
logger.write_string(", globals: ")
self.globals.output(logger)
logger.write_string(", tags: ")
self.tags.output(logger)
logger.write_string(", elems: ")
self.elems.output(logger)
logger.write_string(", datas: ")
self.datas.output(logger)
logger.write_string(", data_count: ")
self.data_count.output(logger)
logger.write_string(", ref_types: ")
self.ref_types.output(logger)
logger.write_string(", v128: ")
self.v128.output(logger)
logger.write_string(", calls: ")
self.calls.output(logger)
logger.write_string(", call_indirect: ")
self.call_indirect.output(logger)
logger.write_string(", branch_heavy_control: ")
self.branch_heavy_control.output(logger)
logger.write_string(", payload_control_flow: ")
self.payload_control_flow.output(logger)
logger.write_string(", multivalue_control_flow: ")
self.multivalue_control_flow.output(logger)
logger.write_string(", numeric_full_ops: ")
self.numeric_full_ops.output(logger)
logger.write_string(", br_table: ")
self.br_table.output(logger)
logger.write_string(", standalone_unreachable: ")
self.standalone_unreachable.output(logger)
logger.write_string(", local_tee: ")
self.local_tee.output(logger)
logger.write_string(", typed_select: ")
self.typed_select.output(logger)
logger.write_string(", tail_calls: ")
self.tail_calls.output(logger)
logger.write_string(", high_local_indices: ")
self.high_local_indices.output(logger)
logger.write_string(", unused_locals: ")
self.unused_locals.output(logger)
logger.write_string(", write_only_locals: ")
self.write_only_locals.output(logger)
logger.write_string(", zero_local_funcs: ")
self.zero_local_funcs.output(logger)
logger.write_string(", multi_param_result_arities: ")
self.multi_param_result_arities.output(logger)
logger.write_string(", empty_body_funcs: ")
self.empty_body_funcs.output(logger)
logger.write_string(", unreachable_result_bodies: ")
self.unreachable_result_bodies.output(logger)
logger.write_string(", local_name_entries: ")
self.local_name_entries.output(logger)
logger.write_string(", scalar_memory_widths: ")
self.scalar_memory_widths.output(logger)
logger.write_string(", nonzero_memarg: ")
self.nonzero_memarg.output(logger)
logger.write_string(", memory_limit_variants: ")
self.memory_limit_variants.output(logger)
logger.write_string(", table_limit_variants: ")
self.table_limit_variants.output(logger)
logger.write_string(", const_expr_variants: ")
self.const_expr_variants.output(logger)
logger.write_string(", basic_ref_instructions: ")
self.basic_ref_instructions.output(logger)
logger.write_string(", i31_extern_conversions: ")
self.i31_extern_conversions.output(logger)
logger.write_string(", simd_phase1: ")
self.simd_phase1.output(logger)
logger.write_string(", simd_phase2: ")
self.simd_phase2.output(logger)
logger.write_string(", simd_phase3: ")
self.simd_phase3.output(logger)
logger.write_string(", descriptors: ")
self.descriptors.output(logger)
logger.write_string(", continuations: ")
self.continuations.output(logger)
logger.write_string(", waitqueues: ")
self.waitqueues.output(logger)
logger.write_string(", atomics: ")
self.atomics.output(logger)
logger.write_string(", array_memory: ")
self.array_memory.output(logger)
logger.write_string(", gc_constructors: ")
self.gc_constructors.output(logger)
logger.write_string(", gc_accessors: ")
self.gc_accessors.output(logger)
logger.write_string(", string_ops: ")
self.string_ops.output(logger)
logger.write_string(", exception_try_table_matrix: ")
self.exception_try_table_matrix.output(logger)
logger.write_string(", subtyping_topology: ")
self.subtyping_topology.output(logger)
logger.write_string(", rich_gc_field_plans: ")
self.rich_gc_field_plans.output(logger)
logger.write_string(", import_export_topology: ")
self.import_export_topology.output(logger)
logger.write_string(", element_segment_range: ")
self.element_segment_range.output(logger)
logger.write_string(", data_segment_range: ")
self.data_segment_range.output(logger)
logger.write_string(", name_custom_sections: ")
self.name_custom_sections.output(logger)
logger.write_string(", gc_exception_combo: ")
self.gc_exception_combo.output(logger)
logger.write_string(", gc_tail_call_combo: ")
self.gc_tail_call_combo.output(logger)
logger.write_string(", shared_memory_atomics: ")
self.shared_memory_atomics.output(logger)
logger.write_string(", imports_start_exports: ")
self.imports_start_exports.output(logger)
logger.write_string(", ssa_straight_line_local_chain: ")
self.ssa_straight_line_local_chain.output(logger)
logger.write_string(", ssa_already_ssa_local: ")
self.ssa_already_ssa_local.output(logger)
logger.write_string(", ssa_multi_def_same_local: ")
self.ssa_multi_def_same_local.output(logger)
logger.write_string(", ssa_param_entry_read: ")
self.ssa_param_entry_read.output(logger)
logger.write_string(", ssa_local_tee_def_use: ")
self.ssa_local_tee_def_use.output(logger)
logger.write_string(", ssa_tee_freshen_candidate: ")
self.ssa_tee_freshen_candidate.output(logger)
logger.write_string(", ssa_tee_merge_feeding_candidate: ")
self.ssa_tee_merge_feeding_candidate.output(logger)
logger.write_string(", ssa_tee_child_expression: ")
self.ssa_tee_child_expression.output(logger)
logger.write_string(", ssa_param_write: ")
self.ssa_param_write.output(logger)
logger.write_string(", ssa_dead_local_set: ")
self.ssa_dead_local_set.output(logger)
logger.write_string(", ssa_dead_local_tee: ")
self.ssa_dead_local_tee.output(logger)
logger.write_string(", ssa_if_join_phi_candidate: ")
self.ssa_if_join_phi_candidate.output(logger)
logger.write_string(", ssa_loop_backedge_phi_candidate: ")
self.ssa_loop_backedge_phi_candidate.output(logger)
logger.write_string(", ssa_br_table_phi_candidate: ")
self.ssa_br_table_phi_candidate.output(logger)
logger.write_string(", ssa_parallel_copy_candidate: ")
self.ssa_parallel_copy_candidate.output(logger)
logger.write_string(", ssa_parallel_copy_cycle_candidate: ")
self.ssa_parallel_copy_cycle_candidate.output(logger)
logger.write_string(", ssa_default_local_merge: ")
self.ssa_default_local_merge.output(logger)
logger.write_string(", ssa_one_arm_default_merge: ")
self.ssa_one_arm_default_merge.output(logger)
logger.write_string(", ssa_one_arm_param_merge: ")
self.ssa_one_arm_param_merge.output(logger)
logger.write_string(", ssa_both_arm_local_merge: ")
self.ssa_both_arm_local_merge.output(logger)
logger.write_string(", ssa_loop_carried_local_merge: ")
self.ssa_loop_carried_local_merge.output(logger)
logger.write_string(", ssa_mixed_fresh_canonical_writes: ")
self.ssa_mixed_fresh_canonical_writes.output(logger)
logger.write_string(", ssa_unreachable_local_carrier: ")
self.ssa_unreachable_local_carrier.output(logger)
logger.write_string(", ssa_dropped_increment_guard_shape: ")
self.ssa_dropped_increment_guard_shape.output(logger)
logger.write_string(", ssa_dropped_increment_reversed_boundary: ")
self.ssa_dropped_increment_reversed_boundary.output(logger)
logger.write_string(", ssa_exceptional_fail_closed_shape: ")
self.ssa_exceptional_fail_closed_shape.output(logger)
logger.write_string(", ssa_typed_loop_param_fail_closed_shape: ")
self.ssa_typed_loop_param_fail_closed_shape.output(logger)
logger.write_string(", ssa_nested_cfg_fail_closed_shape: ")
self.ssa_nested_cfg_fail_closed_shape.output(logger)
logger.write_string(", ssa_nested_result_if_supported_shape: ")
self.ssa_nested_result_if_supported_shape.output(logger)
logger.write_string(", ssa_nested_result_if_condition_write: ")
self.ssa_nested_result_if_condition_write.output(logger)
logger.write_string(", ssa_nested_result_if_condition_value_block: ")
self.ssa_nested_result_if_condition_value_block.output(logger)
logger.write_string(", ssa_nested_result_if_arm_value_block: ")
self.ssa_nested_result_if_arm_value_block.output(logger)
logger.write_string(", ssa_nested_result_if_mixed_arm_value_block: ")
self.ssa_nested_result_if_mixed_arm_value_block.output(logger)
logger.write_string(", ssa_nested_result_if_scalar_result: ")
self.ssa_nested_result_if_scalar_result.output(logger)
logger.write_string(", ssa_structured_early_return_local: ")
self.ssa_structured_early_return_local.output(logger)
logger.write_string(", ssa_block_branch_merge_copy: ")
self.ssa_block_branch_merge_copy.output(logger)
logger.write_string(", ssa_block_br_if_merge_copy: ")
self.ssa_block_br_if_merge_copy.output(logger)
logger.write_string(", ssa_structured_param_merge: ")
self.ssa_structured_param_merge.output(logger)
logger.write_string(", ssa_branch_local_not_read_later: ")
self.ssa_branch_local_not_read_later.output(logger)
logger.write_string(", ssa_default_local_read_after_branchy_control: ")
self.ssa_default_local_read_after_branchy_control.output(logger)
logger.write_string(
", ssa_dropped_unreachable_debris_before_hard_unreachable: ",
)
self.ssa_dropped_unreachable_debris_before_hard_unreachable.output(logger)
logger.write_string(", ssa_canonical_body_local_next_read: ")
self.ssa_canonical_body_local_next_read.output(logger)
logger.write_string(", ssa_immediate_block_exit_canonical_set_br: ")
self.ssa_immediate_block_exit_canonical_set_br.output(logger)
logger.write_string(", ssa_enclosing_label_copy_before_exit: ")
self.ssa_enclosing_label_copy_before_exit.output(logger)
logger.write_string(", ssa_branch_block_alias_copy: ")
self.ssa_branch_block_alias_copy.output(logger)
logger.write_string(", ssa_nested_enclosing_label_copy: ")
self.ssa_nested_enclosing_label_copy.output(logger)
logger.write_string(", ssa_parallel_branch_carrier_copy: ")
self.ssa_parallel_branch_carrier_copy.output(logger)
logger.write_string(", ssa_tee_branch_carrier_copy: ")
self.ssa_tee_branch_carrier_copy.output(logger)
logger.write_string(", ssa_void_br_table_canonical_copies: ")
self.ssa_void_br_table_canonical_copies.output(logger)
logger.write_string(", ssa_branch_operand_local_boundary: ")
self.ssa_branch_operand_local_boundary.output(logger)
logger.write_string(", ssa_nested_loop_target_boundary: ")
self.ssa_nested_loop_target_boundary.output(logger)
logger.write_string(", ssa_large_structured_local_mix: ")
self.ssa_large_structured_local_mix.output(logger)
logger.write_string(", exact_opcode_counts: ")
self.exact_opcode_counts.output(logger)
logger.write_char('}')
}
///|
pub fn GenValidFeatureStats::empty(mode : GenValidMode) -> GenValidFeatureStats {
{
mode,
modules: 0,
imports: 0,
func_exports: 0,
table_exports: 0,
mem_exports: 0,
global_exports: 0,
tag_exports: 0,
starts: 0,
lacks_start: 0,
tables: 0,
mems: 0,
globals: 0,
tags: 0,
elems: 0,
datas: 0,
data_count: 0,
ref_types: 0,
v128: 0,
calls: 0,
call_indirect: 0,
branch_heavy_control: 0,
payload_control_flow: 0,
multivalue_control_flow: 0,
numeric_full_ops: 0,
br_table: 0,
standalone_unreachable: 0,
local_tee: 0,
typed_select: 0,
tail_calls: 0,
high_local_indices: 0,
unused_locals: 0,
write_only_locals: 0,
zero_local_funcs: 0,
multi_param_result_arities: 0,
empty_body_funcs: 0,
unreachable_result_bodies: 0,
local_name_entries: 0,
scalar_memory_widths: 0,
nonzero_memarg: 0,
memory_limit_variants: 0,
table_limit_variants: 0,
const_expr_variants: 0,
basic_ref_instructions: 0,
i31_extern_conversions: 0,
simd_phase1: 0,
simd_phase2: 0,
simd_phase3: 0,
descriptors: 0,
continuations: 0,
waitqueues: 0,
atomics: 0,
array_memory: 0,
gc_constructors: 0,
gc_accessors: 0,
string_ops: 0,
exception_try_table_matrix: 0,
subtyping_topology: 0,
rich_gc_field_plans: 0,
import_export_topology: 0,
element_segment_range: 0,
data_segment_range: 0,
name_custom_sections: 0,
gc_exception_combo: 0,
gc_tail_call_combo: 0,
shared_memory_atomics: 0,
imports_start_exports: 0,
semantic_effects: 0,
import_event_channel: 0,
trap_frontier: 0,
resource_observation: 0,
poisoned_dead_code: 0,
ssa_straight_line_local_chain: 0,
ssa_already_ssa_local: 0,
ssa_multi_def_same_local: 0,
ssa_param_entry_read: 0,
ssa_local_tee_def_use: 0,
ssa_tee_freshen_candidate: 0,
ssa_tee_merge_feeding_candidate: 0,
ssa_tee_child_expression: 0,
ssa_param_write: 0,
ssa_dead_local_set: 0,
ssa_dead_local_tee: 0,
ssa_if_join_phi_candidate: 0,
ssa_loop_backedge_phi_candidate: 0,
ssa_br_table_phi_candidate: 0,
ssa_parallel_copy_candidate: 0,
ssa_parallel_copy_cycle_candidate: 0,
ssa_default_local_merge: 0,
ssa_one_arm_default_merge: 0,
ssa_one_arm_param_merge: 0,
ssa_both_arm_local_merge: 0,
ssa_loop_carried_local_merge: 0,
ssa_mixed_fresh_canonical_writes: 0,
ssa_unreachable_local_carrier: 0,
ssa_dropped_increment_guard_shape: 0,
ssa_dropped_increment_reversed_boundary: 0,
ssa_exceptional_fail_closed_shape: 0,
ssa_typed_loop_param_fail_closed_shape: 0,
ssa_nested_cfg_fail_closed_shape: 0,
ssa_nested_result_if_supported_shape: 0,
ssa_nested_result_if_condition_write: 0,
ssa_nested_result_if_condition_value_block: 0,
ssa_nested_result_if_arm_value_block: 0,
ssa_nested_result_if_mixed_arm_value_block: 0,
ssa_nested_result_if_scalar_result: 0,
ssa_structured_early_return_local: 0,
ssa_block_branch_merge_copy: 0,
ssa_block_br_if_merge_copy: 0,
ssa_structured_param_merge: 0,
ssa_branch_local_not_read_later: 0,
ssa_default_local_read_after_branchy_control: 0,
ssa_dropped_unreachable_debris_before_hard_unreachable: 0,
ssa_canonical_body_local_next_read: 0,
ssa_immediate_block_exit_canonical_set_br: 0,
ssa_enclosing_label_copy_before_exit: 0,
ssa_branch_block_alias_copy: 0,
ssa_nested_enclosing_label_copy: 0,
ssa_parallel_branch_carrier_copy: 0,
ssa_tee_branch_carrier_copy: 0,
ssa_void_br_table_canonical_copies: 0,
ssa_branch_operand_local_boundary: 0,
ssa_nested_loop_target_boundary: 0,
ssa_large_structured_local_mix: 0,
exact_opcode_counts: GenValidExactOpcodeCounts::empty(),
}
}
///|
pub fn GenValidFeatureStats::record(
self : GenValidFeatureStats,
facts : GenValidFeatureFacts,
) -> GenValidFeatureStats {
GenValidFeatureStats::{
..self,
modules: self.modules + 1,
imports: self.imports + gen_valid_bool_count(facts.has_imports),
func_exports: self.func_exports +
gen_valid_bool_count(facts.has_func_exports),
table_exports: self.table_exports +
gen_valid_bool_count(facts.has_table_exports),
mem_exports: self.mem_exports + gen_valid_bool_count(facts.has_mem_exports),
global_exports: self.global_exports +
gen_valid_bool_count(facts.has_global_exports),
tag_exports: self.tag_exports + gen_valid_bool_count(facts.has_tag_exports),
starts: self.starts + gen_valid_bool_count(facts.has_start),
lacks_start: self.lacks_start + gen_valid_bool_count(facts.lacks_start),
tables: self.tables + gen_valid_bool_count(facts.has_tables),
mems: self.mems + gen_valid_bool_count(facts.has_mems),
globals: self.globals + gen_valid_bool_count(facts.has_globals),
tags: self.tags + gen_valid_bool_count(facts.has_tags),
elems: self.elems + gen_valid_bool_count(facts.has_elems),
datas: self.datas + gen_valid_bool_count(facts.has_datas),
data_count: self.data_count + gen_valid_bool_count(facts.has_data_count),
ref_types: self.ref_types + gen_valid_bool_count(facts.uses_ref_types),
v128: self.v128 + gen_valid_bool_count(facts.uses_v128),
calls: self.calls + gen_valid_bool_count(facts.has_call),
call_indirect: self.call_indirect +
gen_valid_bool_count(facts.has_call_indirect),
branch_heavy_control: self.branch_heavy_control +
gen_valid_bool_count(facts.has_branch_heavy_control),
payload_control_flow: self.payload_control_flow +
gen_valid_bool_count(facts.has_payload_control_flow),
multivalue_control_flow: self.multivalue_control_flow +
gen_valid_bool_count(facts.has_multivalue_control_flow),
numeric_full_ops: self.numeric_full_ops +
gen_valid_bool_count(facts.has_numeric_full_ops),
br_table: self.br_table + gen_valid_bool_count(facts.has_br_table),
standalone_unreachable: self.standalone_unreachable +
gen_valid_bool_count(facts.has_standalone_unreachable),
local_tee: self.local_tee + gen_valid_bool_count(facts.has_local_tee),
typed_select: self.typed_select +
gen_valid_bool_count(facts.has_typed_select),
tail_calls: self.tail_calls + gen_valid_bool_count(facts.has_tail_calls),
high_local_indices: self.high_local_indices +
gen_valid_bool_count(facts.has_high_local_indices),
unused_locals: self.unused_locals +
gen_valid_bool_count(facts.has_unused_locals),
write_only_locals: self.write_only_locals +
gen_valid_bool_count(facts.has_write_only_locals),
zero_local_funcs: self.zero_local_funcs +
gen_valid_bool_count(facts.has_zero_local_funcs),
multi_param_result_arities: self.multi_param_result_arities +
gen_valid_bool_count(facts.has_multi_param_result_arities),
empty_body_funcs: self.empty_body_funcs +
gen_valid_bool_count(facts.has_empty_body_funcs),
unreachable_result_bodies: self.unreachable_result_bodies +
gen_valid_bool_count(facts.has_unreachable_result_bodies),
local_name_entries: self.local_name_entries +
gen_valid_bool_count(facts.has_local_name_entries),
scalar_memory_widths: self.scalar_memory_widths +
gen_valid_bool_count(facts.has_scalar_memory_widths),
nonzero_memarg: self.nonzero_memarg +
gen_valid_bool_count(facts.has_nonzero_memarg),
memory_limit_variants: self.memory_limit_variants +
gen_valid_bool_count(facts.has_memory_limit_variants),
table_limit_variants: self.table_limit_variants +
gen_valid_bool_count(facts.has_table_limit_variants),
const_expr_variants: self.const_expr_variants +
gen_valid_bool_count(facts.has_const_expr_variants),
basic_ref_instructions: self.basic_ref_instructions +
gen_valid_bool_count(facts.has_basic_ref_instructions),
i31_extern_conversions: self.i31_extern_conversions +
gen_valid_bool_count(facts.has_i31_extern_conversions),
simd_phase1: self.simd_phase1 + gen_valid_bool_count(facts.has_simd_phase1),
simd_phase2: self.simd_phase2 + gen_valid_bool_count(facts.has_simd_phase2),
simd_phase3: self.simd_phase3 + gen_valid_bool_count(facts.has_simd_phase3),
descriptors: self.descriptors + gen_valid_bool_count(facts.has_descriptors),
continuations: self.continuations +
gen_valid_bool_count(facts.has_continuations),
waitqueues: self.waitqueues + gen_valid_bool_count(facts.has_waitqueues),
atomics: self.atomics + gen_valid_bool_count(facts.has_atomics),
array_memory: self.array_memory +
gen_valid_bool_count(facts.has_array_memory),
gc_constructors: self.gc_constructors +
gen_valid_bool_count(facts.has_gc_constructors),
gc_accessors: self.gc_accessors +
gen_valid_bool_count(facts.has_gc_accessors),
string_ops: self.string_ops + gen_valid_bool_count(facts.has_string_ops),
exception_try_table_matrix: self.exception_try_table_matrix +
gen_valid_bool_count(facts.has_exception_try_table_matrix),
subtyping_topology: self.subtyping_topology +
gen_valid_bool_count(facts.has_subtyping_topology),
rich_gc_field_plans: self.rich_gc_field_plans +
gen_valid_bool_count(facts.has_rich_gc_field_plans),
import_export_topology: self.import_export_topology +
gen_valid_bool_count(facts.has_import_export_topology),
element_segment_range: self.element_segment_range +
gen_valid_bool_count(facts.has_element_segment_range),
data_segment_range: self.data_segment_range +
gen_valid_bool_count(facts.has_data_segment_range),
name_custom_sections: self.name_custom_sections +
gen_valid_bool_count(facts.has_name_custom_sections),
gc_exception_combo: self.gc_exception_combo +
gen_valid_bool_count(facts.has_gc_exception_combo),
gc_tail_call_combo: self.gc_tail_call_combo +
gen_valid_bool_count(facts.has_gc_tail_call_combo),
shared_memory_atomics: self.shared_memory_atomics +
gen_valid_bool_count(facts.has_shared_memory_atomics),
imports_start_exports: self.imports_start_exports +
gen_valid_bool_count(facts.has_imports_start_exports),
semantic_effects: self.semantic_effects +
gen_valid_bool_count(facts.has_semantic_effects),
import_event_channel: self.import_event_channel +
gen_valid_bool_count(facts.has_import_event_channel),
trap_frontier: self.trap_frontier +
gen_valid_bool_count(facts.has_trap_frontier),
resource_observation: self.resource_observation +
gen_valid_bool_count(facts.has_resource_observation),
poisoned_dead_code: self.poisoned_dead_code +
gen_valid_bool_count(facts.has_poisoned_dead_code),
ssa_straight_line_local_chain: self.ssa_straight_line_local_chain +
gen_valid_bool_count(facts.has_ssa_straight_line_local_chain),
ssa_already_ssa_local: self.ssa_already_ssa_local +
gen_valid_bool_count(facts.has_ssa_already_ssa_local),
ssa_multi_def_same_local: self.ssa_multi_def_same_local +
gen_valid_bool_count(facts.has_ssa_multi_def_same_local),
ssa_param_entry_read: self.ssa_param_entry_read +
gen_valid_bool_count(facts.has_ssa_param_entry_read),
ssa_local_tee_def_use: self.ssa_local_tee_def_use +
gen_valid_bool_count(facts.has_ssa_local_tee_def_use),
ssa_tee_freshen_candidate: self.ssa_tee_freshen_candidate +
gen_valid_bool_count(facts.has_ssa_tee_freshen_candidate),
ssa_tee_merge_feeding_candidate: self.ssa_tee_merge_feeding_candidate +
gen_valid_bool_count(facts.has_ssa_tee_merge_feeding_candidate),
ssa_tee_child_expression: self.ssa_tee_child_expression +
gen_valid_bool_count(facts.has_ssa_tee_child_expression),
ssa_param_write: self.ssa_param_write +
gen_valid_bool_count(facts.has_ssa_param_write),
ssa_dead_local_set: self.ssa_dead_local_set +
gen_valid_bool_count(facts.has_ssa_dead_local_set),
ssa_dead_local_tee: self.ssa_dead_local_tee +
gen_valid_bool_count(facts.has_ssa_dead_local_tee),
ssa_if_join_phi_candidate: self.ssa_if_join_phi_candidate +
gen_valid_bool_count(facts.has_ssa_if_join_phi_candidate),
ssa_loop_backedge_phi_candidate: self.ssa_loop_backedge_phi_candidate +
gen_valid_bool_count(facts.has_ssa_loop_backedge_phi_candidate),
ssa_br_table_phi_candidate: self.ssa_br_table_phi_candidate +
gen_valid_bool_count(facts.has_ssa_br_table_phi_candidate),
ssa_parallel_copy_candidate: self.ssa_parallel_copy_candidate +
gen_valid_bool_count(facts.has_ssa_parallel_copy_candidate),
ssa_parallel_copy_cycle_candidate: self.ssa_parallel_copy_cycle_candidate +
gen_valid_bool_count(facts.has_ssa_parallel_copy_cycle_candidate),
ssa_default_local_merge: self.ssa_default_local_merge +
gen_valid_bool_count(facts.has_ssa_default_local_merge),
ssa_one_arm_default_merge: self.ssa_one_arm_default_merge +
gen_valid_bool_count(facts.has_ssa_one_arm_default_merge),
ssa_one_arm_param_merge: self.ssa_one_arm_param_merge +
gen_valid_bool_count(facts.has_ssa_one_arm_param_merge),
ssa_both_arm_local_merge: self.ssa_both_arm_local_merge +
gen_valid_bool_count(facts.has_ssa_both_arm_local_merge),
ssa_loop_carried_local_merge: self.ssa_loop_carried_local_merge +
gen_valid_bool_count(facts.has_ssa_loop_carried_local_merge),
ssa_mixed_fresh_canonical_writes: self.ssa_mixed_fresh_canonical_writes +
gen_valid_bool_count(facts.has_ssa_mixed_fresh_canonical_writes),
ssa_unreachable_local_carrier: self.ssa_unreachable_local_carrier +
gen_valid_bool_count(facts.has_ssa_unreachable_local_carrier),
ssa_dropped_increment_guard_shape: self.ssa_dropped_increment_guard_shape +
gen_valid_bool_count(facts.has_ssa_dropped_increment_guard_shape),
ssa_dropped_increment_reversed_boundary: self.ssa_dropped_increment_reversed_boundary +
gen_valid_bool_count(facts.has_ssa_dropped_increment_reversed_boundary),
ssa_exceptional_fail_closed_shape: self.ssa_exceptional_fail_closed_shape +
gen_valid_bool_count(facts.has_ssa_exceptional_fail_closed_shape),
ssa_typed_loop_param_fail_closed_shape: self.ssa_typed_loop_param_fail_closed_shape +
gen_valid_bool_count(facts.has_ssa_typed_loop_param_fail_closed_shape),
ssa_nested_cfg_fail_closed_shape: self.ssa_nested_cfg_fail_closed_shape +
gen_valid_bool_count(facts.has_ssa_nested_cfg_fail_closed_shape),
ssa_nested_result_if_supported_shape: self.ssa_nested_result_if_supported_shape +
gen_valid_bool_count(facts.has_ssa_nested_result_if_supported_shape),
ssa_nested_result_if_condition_write: self.ssa_nested_result_if_condition_write +
gen_valid_bool_count(facts.has_ssa_nested_result_if_condition_write),
ssa_nested_result_if_condition_value_block: self.ssa_nested_result_if_condition_value_block +
gen_valid_bool_count(facts.has_ssa_nested_result_if_condition_value_block),
ssa_nested_result_if_arm_value_block: self.ssa_nested_result_if_arm_value_block +
gen_valid_bool_count(facts.has_ssa_nested_result_if_arm_value_block),
ssa_nested_result_if_mixed_arm_value_block: self.ssa_nested_result_if_mixed_arm_value_block +
gen_valid_bool_count(facts.has_ssa_nested_result_if_mixed_arm_value_block),
ssa_nested_result_if_scalar_result: self.ssa_nested_result_if_scalar_result +
gen_valid_bool_count(facts.has_ssa_nested_result_if_scalar_result),
ssa_structured_early_return_local: self.ssa_structured_early_return_local +
gen_valid_bool_count(facts.has_ssa_structured_early_return_local),
ssa_block_branch_merge_copy: self.ssa_block_branch_merge_copy +
gen_valid_bool_count(facts.has_ssa_block_branch_merge_copy),
ssa_block_br_if_merge_copy: self.ssa_block_br_if_merge_copy +
gen_valid_bool_count(facts.has_ssa_block_br_if_merge_copy),
ssa_structured_param_merge: self.ssa_structured_param_merge +
gen_valid_bool_count(facts.has_ssa_structured_param_merge),
ssa_branch_local_not_read_later: self.ssa_branch_local_not_read_later +
gen_valid_bool_count(facts.has_ssa_branch_local_not_read_later),
ssa_default_local_read_after_branchy_control: self.ssa_default_local_read_after_branchy_control +
gen_valid_bool_count(facts.has_ssa_default_local_read_after_branchy_control),
ssa_dropped_unreachable_debris_before_hard_unreachable: self.ssa_dropped_unreachable_debris_before_hard_unreachable +
gen_valid_bool_count(
facts.has_ssa_dropped_unreachable_debris_before_hard_unreachable,
),
ssa_canonical_body_local_next_read: self.ssa_canonical_body_local_next_read +
gen_valid_bool_count(facts.has_ssa_canonical_body_local_next_read),
ssa_immediate_block_exit_canonical_set_br: self.ssa_immediate_block_exit_canonical_set_br +
gen_valid_bool_count(facts.has_ssa_immediate_block_exit_canonical_set_br),
ssa_enclosing_label_copy_before_exit: self.ssa_enclosing_label_copy_before_exit +
gen_valid_bool_count(facts.has_ssa_enclosing_label_copy_before_exit),
ssa_branch_block_alias_copy: self.ssa_branch_block_alias_copy +
gen_valid_bool_count(facts.has_ssa_branch_block_alias_copy),
ssa_nested_enclosing_label_copy: self.ssa_nested_enclosing_label_copy +
gen_valid_bool_count(facts.has_ssa_nested_enclosing_label_copy),
ssa_parallel_branch_carrier_copy: self.ssa_parallel_branch_carrier_copy +
gen_valid_bool_count(facts.has_ssa_parallel_branch_carrier_copy),
ssa_tee_branch_carrier_copy: self.ssa_tee_branch_carrier_copy +
gen_valid_bool_count(facts.has_ssa_tee_branch_carrier_copy),
ssa_void_br_table_canonical_copies: self.ssa_void_br_table_canonical_copies +
gen_valid_bool_count(facts.has_ssa_void_br_table_canonical_copies),
ssa_branch_operand_local_boundary: self.ssa_branch_operand_local_boundary +
gen_valid_bool_count(facts.has_ssa_branch_operand_local_boundary),
ssa_nested_loop_target_boundary: self.ssa_nested_loop_target_boundary +
gen_valid_bool_count(facts.has_ssa_nested_loop_target_boundary),
ssa_large_structured_local_mix: self.ssa_large_structured_local_mix +
gen_valid_bool_count(facts.has_ssa_large_structured_local_mix),
exact_opcode_counts: self.exact_opcode_counts.add(facts.exact_opcode_counts),
}
}
///|
pub enum GenValidRandomStreamLabel {
ModuleTopologyStream
TypeStream
FuncStream
BodyStream
MemoryStream
TableStream
DataStream
ElemStream
GlobalStream
TagStream
StartStream
InvalidStrategyChoiceStream
InvalidMutationChoiceStream
TextMutationChoiceStream
HarnessShufflingStream
} derive(Eq, Debug)
///|
pub fn gen_valid_random_stream_labels() -> Array[GenValidRandomStreamLabel] {
[
ModuleTopologyStream,
TypeStream,
FuncStream,
BodyStream,
MemoryStream,
TableStream,
DataStream,
ElemStream,
GlobalStream,
TagStream,
StartStream,
InvalidStrategyChoiceStream,
InvalidMutationChoiceStream,
TextMutationChoiceStream,
HarnessShufflingStream,
]
}
///|
pub fn gen_valid_random_stream_label_name(
label : GenValidRandomStreamLabel,
) -> String {
match label {
ModuleTopologyStream => "module-topology"
TypeStream => "types"
FuncStream => "funcs"
BodyStream => "bodies"
MemoryStream => "memories"
TableStream => "tables"
DataStream => "data"
ElemStream => "elems"
GlobalStream => "globals"
TagStream => "tags"
StartStream => "start"
InvalidStrategyChoiceStream => "invalid-strategy-choice"
InvalidMutationChoiceStream => "invalid-mutation-choice"
TextMutationChoiceStream => "text-mutation-choice"
HarnessShufflingStream => "harness-shuffling"
}
}
///|
fn gen_valid_random_stream_label_salt(
label : GenValidRandomStreamLabel,
) -> UInt64 {
match label {
ModuleTopologyStream => 0x1001UL
TypeStream => 0x2002UL
FuncStream => 0x3003UL
BodyStream => 0x4004UL
MemoryStream => 0x5005UL
TableStream => 0x6006UL
DataStream => 0x7007UL
ElemStream => 0x8008UL
GlobalStream => 0xd00dUL
TagStream => 0xe00eUL
StartStream => 0xf00fUL
InvalidStrategyChoiceStream => 0x9009UL
InvalidMutationChoiceStream => 0xa00aUL
TextMutationChoiceStream => 0xb00bUL
HarnessShufflingStream => 0xc00cUL
}
}
///|
pub fn gen_valid_derive_stream_seed(
root_seed : UInt64,
label : GenValidRandomStreamLabel,
) -> UInt64 {
root_seed ^ gen_valid_random_stream_label_salt(label) ^ 0x9e3779b97f4a7c15UL
}
///|
pub fn gen_valid_stream_random_state(
root_seed : UInt64,
label : GenValidRandomStreamLabel,
) -> RandomState {
@splitmix.new(seed=gen_valid_derive_stream_seed(root_seed, label))
}
///|
struct GenValidContext {
rnd : RandomState
root_seed : UInt64
module_topology_rnd : RandomState
type_rnd : RandomState
func_rnd : RandomState
body_rnd : RandomState
memory_rnd : RandomState
table_rnd : RandomState
data_rnd : RandomState
elem_rnd : RandomState
global_rnd : RandomState
tag_rnd : RandomState
start_rnd : RandomState
use_named_streams : Bool
config : GenValidConfig
}
///|
pub struct GenValidExactOpcodeCounts {
i32_const : Int32
i64_const : Int32
f32_const : Int32
f64_const : Int32
i32_eqz : Int32
i64_eqz : Int32
i32_eq : Int32
i32_ne : Int32
i32_lt_s : Int32
i32_lt_u : Int32
i32_gt_s : Int32
i32_gt_u : Int32
i32_le_s : Int32
i32_le_u : Int32
i32_ge_s : Int32
i32_ge_u : Int32
i64_eq : Int32
i64_ne : Int32
i64_lt_s : Int32
i64_lt_u : Int32
i64_gt_s : Int32
i64_gt_u : Int32
i64_le_s : Int32
i64_le_u : Int32
i64_ge_s : Int32
i64_ge_u : Int32
f32_eq : Int32
f32_ne : Int32
f32_lt : Int32
f32_gt : Int32
f32_le : Int32
f32_ge : Int32
f64_eq : Int32
f64_ne : Int32
f64_lt : Int32
f64_gt : Int32
f64_le : Int32
f64_ge : Int32
i32_clz : Int32
i32_ctz : Int32
i32_popcnt : Int32
i32_add : Int32
i32_sub : Int32
i32_mul : Int32
i32_div_s : Int32
i32_div_u : Int32
i32_rem_s : Int32
i32_rem_u : Int32
i32_and : Int32
i32_or : Int32
i32_xor : Int32
i32_shl : Int32
i32_shr_s : Int32
i32_shr_u : Int32
i32_rotl : Int32
i32_rotr : Int32
i64_clz : Int32
i64_ctz : Int32
i64_popcnt : Int32
i64_add : Int32
i64_sub : Int32
i64_mul : Int32
i64_div_s : Int32
i64_div_u : Int32
i64_rem_s : Int32
i64_rem_u : Int32
i64_and : Int32
i64_or : Int32
i64_xor : Int32
i64_shl : Int32
i64_shr_s : Int32
i64_shr_u : Int32
i64_rotl : Int32
i64_rotr : Int32
f32_abs : Int32
f32_neg : Int32
f32_ceil : Int32
f32_floor : Int32
f32_trunc : Int32
f32_nearest : Int32
f32_sqrt : Int32
f32_add : Int32
f32_sub : Int32
f32_mul : Int32
f32_div : Int32
f32_min : Int32
f32_max : Int32
f32_copysign : Int32
f64_abs : Int32
f64_neg : Int32
f64_ceil : Int32
f64_floor : Int32
f64_trunc : Int32
f64_nearest : Int32
f64_sqrt : Int32
f64_add : Int32
f64_sub : Int32
f64_mul : Int32
f64_div : Int32
f64_min : Int32
f64_max : Int32
f64_copysign : Int32
i32_wrap_i64 : Int32
i32_trunc_f32s : Int32
i32_trunc_f32u : Int32
i32_trunc_f64s : Int32
i32_trunc_f64u : Int32
i64_extend_i32s : Int32
i64_extend_i32u : Int32
i64_trunc_f32s : Int32
i64_trunc_f32u : Int32
i64_trunc_f64s : Int32
i64_trunc_f64u : Int32
f32_convert_i32s : Int32
f32_convert_i32u : Int32
f32_convert_i64s : Int32
f32_convert_i64u : Int32
f32_demote_f64 : Int32
f64_convert_i32s : Int32
f64_convert_i32u : Int32
f64_convert_i64s : Int32
f64_convert_i64u : Int32
f64_promote_f32 : Int32
i32_extend8s : Int32
i32_extend16s : Int32
i64_extend8s : Int32
i64_extend16s : Int32
i64_extend32s : Int32
i32_trunc_sat_f32s : Int32
i32_trunc_sat_f32u : Int32
i32_trunc_sat_f64s : Int32
i32_trunc_sat_f64u : Int32
i64_trunc_sat_f32s : Int32
i64_trunc_sat_f32u : Int32
i64_trunc_sat_f64s : Int32
i64_trunc_sat_f64u : Int32
i32_reinterpret_f32 : Int32
i64_reinterpret_f64 : Int32
f32_reinterpret_i32 : Int32
f64_reinterpret_i64 : Int32
br_table : Int32
unreachable_opcode : Int32
local_tee : Int32
typed_select : Int32
return_call : Int32
return_call_indirect : Int32
return_call_ref : Int32
v128_const : Int32
i8x16_splat : Int32
i16x8_splat : Int32
i32x4_splat : Int32
i64x2_splat : Int32
f32x4_splat : Int32
f64x2_splat : Int32
i8x16_extract_lane_s : Int32
i8x16_extract_lane_u : Int32
i8x16_replace_lane : Int32
i16x8_extract_lane_s : Int32
i16x8_extract_lane_u : Int32
i16x8_replace_lane : Int32
i32x4_extract_lane : Int32
i32x4_replace_lane : Int32
i64x2_extract_lane : Int32
i64x2_replace_lane : Int32
f32x4_extract_lane : Int32
f32x4_replace_lane : Int32
f64x2_extract_lane : Int32
f64x2_replace_lane : Int32
v128_not : Int32
v128_and : Int32
v128_andnot : Int32
v128_or : Int32
v128_xor : Int32
v128_bitselect : Int32
v128_any_true : Int32
i8x16_eq : Int32
i8x16_ne : Int32
i8x16_lt_s : Int32
i8x16_lt_u : Int32
i8x16_gt_s : Int32
i8x16_gt_u : Int32
i8x16_le_s : Int32
i8x16_le_u : Int32
i8x16_ge_s : Int32
i8x16_ge_u : Int32
i16x8_eq : Int32
i16x8_ne : Int32
i16x8_lt_s : Int32
i16x8_lt_u : Int32
i16x8_gt_s : Int32
i16x8_gt_u : Int32
i16x8_le_s : Int32
i16x8_le_u : Int32
i16x8_ge_s : Int32
i16x8_ge_u : Int32
i32x4_eq : Int32
i32x4_ne : Int32
i32x4_lt_s : Int32
i32x4_lt_u : Int32
i32x4_gt_s : Int32
i32x4_gt_u : Int32
i32x4_le_s : Int32
i32x4_le_u : Int32
i32x4_ge_s : Int32
i32x4_ge_u : Int32
i64x2_eq : Int32
i64x2_ne : Int32
i64x2_lt_s : Int32
i64x2_gt_s : Int32
i64x2_le_s : Int32
f32x4_eq : Int32
f32x4_ne : Int32
f32x4_lt : Int32
f32x4_gt : Int32
f32x4_le : Int32
f32x4_ge : Int32
f64x2_eq : Int32
f64x2_ne : Int32
f64x2_lt : Int32
f64x2_gt : Int32
f64x2_le : Int32
f64x2_ge : Int32
i8x16_abs : Int32
i8x16_neg : Int32
i8x16_popcnt : Int32
i8x16_all_true : Int32
i8x16_bitmask : Int32
i16x8_abs : Int32
i16x8_neg : Int32
i16x8_q15mulr_sat_s : Int32
i16x8_all_true : Int32
i16x8_bitmask : Int32
i32x4_abs : Int32
i32x4_neg : Int32
i32x4_bitmask : Int32
i64x2_abs : Int32
i64x2_neg : Int32
i64x2_all_true : Int32
i8x16_add : Int32
i8x16_add_sat_s : Int32
i8x16_add_sat_u : Int32
i8x16_sub : Int32
i8x16_sub_sat_s : Int32
i16x8_mul : Int32
i8x16_shl : Int32
i8x16_shr_s : Int32
i8x16_shr_u : Int32
i16x8_shl : Int32
i16x8_shr_s : Int32
i16x8_shr_u : Int32
i32x4_shl : Int32
i32x4_shr_s : Int32
i32x4_shr_u : Int32
i64x2_shl : Int32
i64x2_shr_s : Int32
i64x2_shr_u : Int32
i64x2_ge_s : Int32
i32x4_all_true : Int32
i64x2_bitmask : Int32
i8x16_sub_sat_u : Int32
i8x16_min_s : Int32
i8x16_min_u : Int32
i8x16_max_s : Int32
i8x16_max_u : Int32
i8x16_avgr_u : Int32
i16x8_add : Int32
i16x8_add_sat_s : Int32
i16x8_add_sat_u : Int32
i16x8_sub : Int32
i16x8_sub_sat_s : Int32
i16x8_sub_sat_u : Int32
i16x8_min_s : Int32
i16x8_min_u : Int32
i16x8_max_s : Int32
i16x8_max_u : Int32
i16x8_avgr_u : Int32
i32x4_add : Int32
i32x4_sub : Int32
i32x4_mul : Int32
i32x4_min_s : Int32
i32x4_min_u : Int32
i32x4_max_s : Int32
i32x4_max_u : Int32
i64x2_add : Int32
i64x2_sub : Int32
i64x2_mul : Int32
f32x4_add : Int32
f32x4_abs : Int32
f32x4_neg : Int32
f32x4_sqrt : Int32
f32x4_sub : Int32
f32x4_mul : Int32
f32x4_div : Int32
f32x4_min : Int32
f32x4_max : Int32
f32x4_pmin : Int32
f32x4_pmax : Int32
f64x2_add : Int32
f64x2_abs : Int32
f64x2_neg : Int32
f64x2_sqrt : Int32
f64x2_sub : Int32
f64x2_mul : Int32
f64x2_div : Int32
f64x2_min : Int32
f64x2_max : Int32
f64x2_pmin : Int32
f64x2_pmax : Int32
f32x4_ceil : Int32
f32x4_floor : Int32
f32x4_trunc : Int32
f32x4_nearest : Int32
f64x2_ceil : Int32
f64x2_floor : Int32
f64x2_trunc : Int32
f64x2_nearest : Int32
v128_load8x8_s : Int32
v128_load8x8_u : Int32
v128_load16x4_s : Int32
v128_load16x4_u : Int32
v128_load32x2_s : Int32
v128_load32x2_u : Int32
v128_load8_splat : Int32
v128_load16_splat : Int32
v128_load32_splat : Int32
v128_load64_splat : Int32
v128_load8_lane : Int32
v128_load16_lane : Int32
v128_load32_lane : Int32
v128_load64_lane : Int32
v128_store8_lane : Int32
v128_store16_lane : Int32
v128_store32_lane : Int32
v128_store64_lane : Int32
v128_load32_zero : Int32
v128_load64_zero : Int32
i8x16_narrow_i16x8_u : Int32
i16x8_narrow_i32x4_s : Int32
i16x8_narrow_i32x4_u : Int32
i16x8_extadd_pairwise_i8x16_s : Int32
i16x8_extadd_pairwise_i8x16_u : Int32
i32x4_extadd_pairwise_i16x8_s : Int32
i32x4_extadd_pairwise_i16x8_u : Int32
i16x8_extend_low_i8x16_s : Int32
i16x8_extend_high_i8x16_s : Int32
i16x8_extend_low_i8x16_u : Int32
i16x8_extend_high_i8x16_u : Int32
i32x4_extend_low_i16x8_s : Int32
i32x4_extend_high_i16x8_s : Int32
i32x4_extend_low_i16x8_u : Int32
i32x4_extend_high_i16x8_u : Int32
i64x2_extend_low_i32x4_s : Int32
i64x2_extend_high_i32x4_s : Int32
i64x2_extend_low_i32x4_u : Int32
i64x2_extend_high_i32x4_u : Int32
i16x8_extmul_low_i8x16_s : Int32
i16x8_extmul_high_i8x16_s : Int32
i16x8_extmul_low_i8x16_u : Int32
i16x8_extmul_high_i8x16_u : Int32
i32x4_extmul_low_i16x8_s : Int32
i32x4_extmul_high_i16x8_s : Int32
i32x4_extmul_low_i16x8_u : Int32
i32x4_extmul_high_i16x8_u : Int32
i64x2_extmul_low_i32x4_s : Int32
i64x2_extmul_high_i32x4_s : Int32
i64x2_extmul_low_i32x4_u : Int32
i64x2_extmul_high_i32x4_u : Int32
f64x2_promote_low_f32x4 : Int32
v128_load : Int32
v128_store : Int32
i8x16_shuffle : Int32
i8x16_swizzle : Int32
i8x16_narrow_i16x8_s : Int32
i32x4_dot_i16x8_s : Int32
f32x4_demote_f64x2_zero : Int32
i32x4_trunc_sat_f32x4_s : Int32
i32x4_trunc_sat_f32x4_u : Int32
f32x4_convert_i32x4_s : Int32
f32x4_convert_i32x4_u : Int32
i32x4_trunc_sat_f64x2_s_zero : Int32
i32x4_trunc_sat_f64x2_u_zero : Int32
f64x2_convert_low_i32x4_s : Int32
f64x2_convert_low_i32x4_u : Int32
i8x16_relaxed_swizzle : Int32
i32x4_relaxed_trunc_f32x4_s : Int32
i32x4_relaxed_trunc_f32x4_u : Int32
i32x4_relaxed_trunc_zero_f64x2_s : Int32
i32x4_relaxed_trunc_zero_f64x2_u : Int32
f32x4_relaxed_madd : Int32
f32x4_relaxed_nmadd : Int32
f64x2_relaxed_madd : Int32
f64x2_relaxed_nmadd : Int32
i8x16_relaxed_laneselect : Int32
i16x8_relaxed_laneselect : Int32
i32x4_relaxed_laneselect : Int32
i64x2_relaxed_laneselect : Int32
f32x4_relaxed_min : Int32
f32x4_relaxed_max : Int32
f64x2_relaxed_min : Int32
f64x2_relaxed_max : Int32
i16x8_relaxed_q15mulr_s : Int32
i16x8_relaxed_dot_i8x16_i7x16_s : Int32
i32x4_relaxed_dot_i8x16_i7x16_add_s : Int32
} derive(Eq, Debug)
///|
priv struct GenValidInstrFacts {
uses_ref_types : Bool
uses_v128 : Bool
has_call : Bool
has_call_indirect : Bool
has_numeric_full_ops : Bool
has_br_table : Bool
has_payload_control_flow : Bool
has_multivalue_control_flow : Bool
has_standalone_unreachable : Bool
has_local_tee : Bool
has_typed_select : Bool
has_tail_calls : Bool
has_scalar_memory_widths : Bool
has_nonzero_memarg : Bool
has_memory_limit_variants : Bool
has_basic_ref_instructions : Bool
has_i31_extern_conversions : Bool
has_simd_phase1 : Bool
has_simd_phase2 : Bool
has_simd_phase3 : Bool
has_atomics : Bool
has_gc_constructors : Bool
has_gc_accessors : Bool
has_string_ops : Bool
has_exception_try_table_matrix : Bool
has_subtyping_topology : Bool
has_rich_gc_field_plans : Bool
has_shared_memories : Bool
exact_opcode_counts : GenValidExactOpcodeCounts
control_nodes : Int32
branch_ops : Int32
}
///|
fn GenValidContext::new(
rnd : RandomState,
config : GenValidConfig,
) -> GenValidContext {
{
rnd,
root_seed: 0UL,
module_topology_rnd: rnd,
type_rnd: rnd,
func_rnd: rnd,
body_rnd: rnd,
memory_rnd: rnd,
table_rnd: rnd,
data_rnd: rnd,
elem_rnd: rnd,
global_rnd: rnd,
tag_rnd: rnd,
start_rnd: rnd,
use_named_streams: false,
config,
}
}
///|
fn GenValidContext::new_streamed(
root_seed : UInt64,
config : GenValidConfig,
) -> GenValidContext {
{
rnd: gen_valid_stream_random_state(root_seed, ModuleTopologyStream),
root_seed,
module_topology_rnd: gen_valid_stream_random_state(
root_seed,
ModuleTopologyStream,
),
type_rnd: gen_valid_stream_random_state(root_seed, TypeStream),
func_rnd: gen_valid_stream_random_state(root_seed, FuncStream),
body_rnd: gen_valid_stream_random_state(root_seed, BodyStream),
memory_rnd: gen_valid_stream_random_state(root_seed, MemoryStream),
table_rnd: gen_valid_stream_random_state(root_seed, TableStream),
data_rnd: gen_valid_stream_random_state(root_seed, DataStream),
elem_rnd: gen_valid_stream_random_state(root_seed, ElemStream),
global_rnd: gen_valid_stream_random_state(root_seed, GlobalStream),
tag_rnd: gen_valid_stream_random_state(root_seed, TagStream),
start_rnd: gen_valid_stream_random_state(root_seed, StartStream),
use_named_streams: true,
config,
}
}
///|
pub fn GenValidExactOpcodeCounts::empty() -> GenValidExactOpcodeCounts {
{
i32_const: 0,
i64_const: 0,
f32_const: 0,
f64_const: 0,
i32_eqz: 0,
i64_eqz: 0,
i32_eq: 0,
i32_ne: 0,
i32_lt_s: 0,
i32_lt_u: 0,
i32_gt_s: 0,
i32_gt_u: 0,
i32_le_s: 0,
i32_le_u: 0,
i32_ge_s: 0,
i32_ge_u: 0,
i64_eq: 0,
i64_ne: 0,
i64_lt_s: 0,
i64_lt_u: 0,
i64_gt_s: 0,
i64_gt_u: 0,
i64_le_s: 0,
i64_le_u: 0,
i64_ge_s: 0,
i64_ge_u: 0,
f32_eq: 0,
f32_ne: 0,
f32_lt: 0,
f32_gt: 0,
f32_le: 0,
f32_ge: 0,
f64_eq: 0,
f64_ne: 0,
f64_lt: 0,
f64_gt: 0,
f64_le: 0,
f64_ge: 0,
i32_clz: 0,
i32_ctz: 0,
i32_popcnt: 0,
i32_add: 0,
i32_sub: 0,
i32_mul: 0,
i32_div_s: 0,
i32_div_u: 0,
i32_rem_s: 0,
i32_rem_u: 0,
i32_and: 0,
i32_or: 0,
i32_xor: 0,
i32_shl: 0,
i32_shr_s: 0,
i32_shr_u: 0,
i32_rotl: 0,
i32_rotr: 0,
i64_clz: 0,
i64_ctz: 0,
i64_popcnt: 0,
i64_add: 0,
i64_sub: 0,
i64_mul: 0,
i64_div_s: 0,
i64_div_u: 0,
i64_rem_s: 0,
i64_rem_u: 0,
i64_and: 0,
i64_or: 0,
i64_xor: 0,
i64_shl: 0,
i64_shr_s: 0,
i64_shr_u: 0,
i64_rotl: 0,
i64_rotr: 0,
f32_abs: 0,
f32_neg: 0,
f32_ceil: 0,
f32_floor: 0,
f32_trunc: 0,
f32_nearest: 0,
f32_sqrt: 0,
f32_add: 0,
f32_sub: 0,
f32_mul: 0,
f32_div: 0,
f32_min: 0,
f32_max: 0,
f32_copysign: 0,
f64_abs: 0,
f64_neg: 0,
f64_ceil: 0,
f64_floor: 0,
f64_trunc: 0,
f64_nearest: 0,
f64_sqrt: 0,
f64_add: 0,
f64_sub: 0,
f64_mul: 0,
f64_div: 0,
f64_min: 0,
f64_max: 0,
f64_copysign: 0,
i32_wrap_i64: 0,
i32_trunc_f32s: 0,
i32_trunc_f32u: 0,
i32_trunc_f64s: 0,
i32_trunc_f64u: 0,
i64_extend_i32s: 0,
i64_extend_i32u: 0,
i64_trunc_f32s: 0,
i64_trunc_f32u: 0,
i64_trunc_f64s: 0,
i64_trunc_f64u: 0,
f32_convert_i32s: 0,
f32_convert_i32u: 0,
f32_convert_i64s: 0,
f32_convert_i64u: 0,
f32_demote_f64: 0,
f64_convert_i32s: 0,
f64_convert_i32u: 0,
f64_convert_i64s: 0,
f64_convert_i64u: 0,
f64_promote_f32: 0,
i32_extend8s: 0,
i32_extend16s: 0,
i64_extend8s: 0,
i64_extend16s: 0,
i64_extend32s: 0,
i32_trunc_sat_f32s: 0,
i32_trunc_sat_f32u: 0,
i32_trunc_sat_f64s: 0,
i32_trunc_sat_f64u: 0,
i64_trunc_sat_f32s: 0,
i64_trunc_sat_f32u: 0,
i64_trunc_sat_f64s: 0,
i64_trunc_sat_f64u: 0,
i32_reinterpret_f32: 0,
i64_reinterpret_f64: 0,
f32_reinterpret_i32: 0,
f64_reinterpret_i64: 0,
br_table: 0,
unreachable_opcode: 0,
local_tee: 0,
typed_select: 0,
return_call: 0,
return_call_indirect: 0,
return_call_ref: 0,
v128_const: 0,
i8x16_splat: 0,
i16x8_splat: 0,
i32x4_splat: 0,
i64x2_splat: 0,
f32x4_splat: 0,
f64x2_splat: 0,
i8x16_extract_lane_s: 0,
i8x16_extract_lane_u: 0,
i8x16_replace_lane: 0,
i16x8_extract_lane_s: 0,
i16x8_extract_lane_u: 0,
i16x8_replace_lane: 0,
i32x4_extract_lane: 0,
i32x4_replace_lane: 0,
i64x2_extract_lane: 0,
i64x2_replace_lane: 0,
f32x4_extract_lane: 0,
f32x4_replace_lane: 0,
f64x2_extract_lane: 0,
f64x2_replace_lane: 0,
v128_not: 0,
v128_and: 0,
v128_andnot: 0,
v128_or: 0,
v128_xor: 0,
v128_bitselect: 0,
v128_any_true: 0,
i8x16_eq: 0,
i8x16_ne: 0,
i8x16_lt_s: 0,
i8x16_lt_u: 0,
i8x16_gt_s: 0,
i8x16_gt_u: 0,
i8x16_le_s: 0,
i8x16_le_u: 0,
i8x16_ge_s: 0,
i8x16_ge_u: 0,
i16x8_eq: 0,
i16x8_ne: 0,
i16x8_lt_s: 0,
i16x8_lt_u: 0,
i16x8_gt_s: 0,
i16x8_gt_u: 0,
i16x8_le_s: 0,
i16x8_le_u: 0,
i16x8_ge_s: 0,
i16x8_ge_u: 0,
i32x4_eq: 0,
i32x4_ne: 0,
i32x4_lt_s: 0,
i32x4_lt_u: 0,
i32x4_gt_s: 0,
i32x4_gt_u: 0,
i32x4_le_s: 0,
i32x4_le_u: 0,
i32x4_ge_s: 0,
i32x4_ge_u: 0,
i64x2_eq: 0,
i64x2_ne: 0,
i64x2_lt_s: 0,
i64x2_gt_s: 0,
i64x2_le_s: 0,
f32x4_eq: 0,
f32x4_ne: 0,
f32x4_lt: 0,
f32x4_gt: 0,
f32x4_le: 0,
f32x4_ge: 0,
f64x2_eq: 0,
f64x2_ne: 0,
f64x2_lt: 0,
f64x2_gt: 0,
f64x2_le: 0,
f64x2_ge: 0,
i8x16_abs: 0,
i8x16_neg: 0,
i8x16_popcnt: 0,
i8x16_all_true: 0,
i8x16_bitmask: 0,
i16x8_abs: 0,
i16x8_neg: 0,
i16x8_q15mulr_sat_s: 0,
i16x8_all_true: 0,
i16x8_bitmask: 0,
i32x4_abs: 0,
i32x4_neg: 0,
i32x4_bitmask: 0,
i64x2_abs: 0,
i64x2_neg: 0,
i64x2_all_true: 0,
i8x16_add: 0,
i8x16_add_sat_s: 0,
i8x16_add_sat_u: 0,
i8x16_sub: 0,
i8x16_sub_sat_s: 0,
i16x8_mul: 0,
i8x16_shl: 0,
i8x16_shr_s: 0,
i8x16_shr_u: 0,
i16x8_shl: 0,
i16x8_shr_s: 0,
i16x8_shr_u: 0,
i32x4_shl: 0,
i32x4_shr_s: 0,
i32x4_shr_u: 0,
i64x2_shl: 0,
i64x2_shr_s: 0,
i64x2_shr_u: 0,
i64x2_ge_s: 0,
i32x4_all_true: 0,
i64x2_bitmask: 0,
i8x16_sub_sat_u: 0,
i8x16_min_s: 0,
i8x16_min_u: 0,
i8x16_max_s: 0,
i8x16_max_u: 0,
i8x16_avgr_u: 0,
i16x8_add: 0,
i16x8_add_sat_s: 0,
i16x8_add_sat_u: 0,
i16x8_sub: 0,
i16x8_sub_sat_s: 0,
i16x8_sub_sat_u: 0,
i16x8_min_s: 0,
i16x8_min_u: 0,
i16x8_max_s: 0,
i16x8_max_u: 0,
i16x8_avgr_u: 0,
i32x4_add: 0,
i32x4_sub: 0,
i32x4_mul: 0,
i32x4_min_s: 0,
i32x4_min_u: 0,
i32x4_max_s: 0,
i32x4_max_u: 0,
i64x2_add: 0,
i64x2_sub: 0,
i64x2_mul: 0,
f32x4_add: 0,
f32x4_abs: 0,
f32x4_neg: 0,
f32x4_sqrt: 0,
f32x4_sub: 0,
f32x4_mul: 0,
f32x4_div: 0,
f32x4_min: 0,
f32x4_max: 0,
f32x4_pmin: 0,
f32x4_pmax: 0,
f64x2_add: 0,
f64x2_abs: 0,
f64x2_neg: 0,
f64x2_sqrt: 0,
f64x2_sub: 0,
f64x2_mul: 0,
f64x2_div: 0,
f64x2_min: 0,
f64x2_max: 0,
f64x2_pmin: 0,
f64x2_pmax: 0,
f32x4_ceil: 0,
f32x4_floor: 0,
f32x4_trunc: 0,
f32x4_nearest: 0,
f64x2_ceil: 0,
f64x2_floor: 0,
f64x2_trunc: 0,
f64x2_nearest: 0,
v128_load8x8_s: 0,
v128_load8x8_u: 0,
v128_load16x4_s: 0,
v128_load16x4_u: 0,
v128_load32x2_s: 0,
v128_load32x2_u: 0,
v128_load8_splat: 0,
v128_load16_splat: 0,
v128_load32_splat: 0,
v128_load64_splat: 0,
v128_load8_lane: 0,
v128_load16_lane: 0,
v128_load32_lane: 0,
v128_load64_lane: 0,
v128_store8_lane: 0,
v128_store16_lane: 0,
v128_store32_lane: 0,
v128_store64_lane: 0,
v128_load32_zero: 0,
v128_load64_zero: 0,
i8x16_narrow_i16x8_u: 0,
i16x8_narrow_i32x4_s: 0,
i16x8_narrow_i32x4_u: 0,
i16x8_extadd_pairwise_i8x16_s: 0,
i16x8_extadd_pairwise_i8x16_u: 0,
i32x4_extadd_pairwise_i16x8_s: 0,
i32x4_extadd_pairwise_i16x8_u: 0,
i16x8_extend_low_i8x16_s: 0,
i16x8_extend_high_i8x16_s: 0,
i16x8_extend_low_i8x16_u: 0,
i16x8_extend_high_i8x16_u: 0,
i32x4_extend_low_i16x8_s: 0,
i32x4_extend_high_i16x8_s: 0,
i32x4_extend_low_i16x8_u: 0,
i32x4_extend_high_i16x8_u: 0,
i64x2_extend_low_i32x4_s: 0,
i64x2_extend_high_i32x4_s: 0,
i64x2_extend_low_i32x4_u: 0,
i64x2_extend_high_i32x4_u: 0,
i16x8_extmul_low_i8x16_s: 0,
i16x8_extmul_high_i8x16_s: 0,
i16x8_extmul_low_i8x16_u: 0,
i16x8_extmul_high_i8x16_u: 0,
i32x4_extmul_low_i16x8_s: 0,
i32x4_extmul_high_i16x8_s: 0,
i32x4_extmul_low_i16x8_u: 0,
i32x4_extmul_high_i16x8_u: 0,
i64x2_extmul_low_i32x4_s: 0,
i64x2_extmul_high_i32x4_s: 0,
i64x2_extmul_low_i32x4_u: 0,
i64x2_extmul_high_i32x4_u: 0,
f64x2_promote_low_f32x4: 0,
v128_load: 0,
v128_store: 0,
i8x16_shuffle: 0,
i8x16_swizzle: 0,
i8x16_narrow_i16x8_s: 0,
i32x4_dot_i16x8_s: 0,
f32x4_demote_f64x2_zero: 0,
i32x4_trunc_sat_f32x4_s: 0,
i32x4_trunc_sat_f32x4_u: 0,
f32x4_convert_i32x4_s: 0,
f32x4_convert_i32x4_u: 0,
i32x4_trunc_sat_f64x2_s_zero: 0,
i32x4_trunc_sat_f64x2_u_zero: 0,
f64x2_convert_low_i32x4_s: 0,
f64x2_convert_low_i32x4_u: 0,
i8x16_relaxed_swizzle: 0,
i32x4_relaxed_trunc_f32x4_s: 0,
i32x4_relaxed_trunc_f32x4_u: 0,
i32x4_relaxed_trunc_zero_f64x2_s: 0,
i32x4_relaxed_trunc_zero_f64x2_u: 0,
f32x4_relaxed_madd: 0,
f32x4_relaxed_nmadd: 0,
f64x2_relaxed_madd: 0,
f64x2_relaxed_nmadd: 0,
i8x16_relaxed_laneselect: 0,
i16x8_relaxed_laneselect: 0,
i32x4_relaxed_laneselect: 0,
i64x2_relaxed_laneselect: 0,
f32x4_relaxed_min: 0,
f32x4_relaxed_max: 0,
f64x2_relaxed_min: 0,
f64x2_relaxed_max: 0,
i16x8_relaxed_q15mulr_s: 0,
i16x8_relaxed_dot_i8x16_i7x16_s: 0,
i32x4_relaxed_dot_i8x16_i7x16_add_s: 0,
}
}
///|
pub fn GenValidExactOpcodeCounts::add(
self : GenValidExactOpcodeCounts,
other : GenValidExactOpcodeCounts,
) -> GenValidExactOpcodeCounts {
{
i32_const: self.i32_const + other.i32_const,
i64_const: self.i64_const + other.i64_const,
f32_const: self.f32_const + other.f32_const,
f64_const: self.f64_const + other.f64_const,
i32_eqz: self.i32_eqz + other.i32_eqz,
i64_eqz: self.i64_eqz + other.i64_eqz,
i32_eq: self.i32_eq + other.i32_eq,
i32_ne: self.i32_ne + other.i32_ne,
i32_lt_s: self.i32_lt_s + other.i32_lt_s,
i32_lt_u: self.i32_lt_u + other.i32_lt_u,
i32_gt_s: self.i32_gt_s + other.i32_gt_s,
i32_gt_u: self.i32_gt_u + other.i32_gt_u,
i32_le_s: self.i32_le_s + other.i32_le_s,
i32_le_u: self.i32_le_u + other.i32_le_u,
i32_ge_s: self.i32_ge_s + other.i32_ge_s,
i32_ge_u: self.i32_ge_u + other.i32_ge_u,
i64_eq: self.i64_eq + other.i64_eq,
i64_ne: self.i64_ne + other.i64_ne,
i64_lt_s: self.i64_lt_s + other.i64_lt_s,
i64_lt_u: self.i64_lt_u + other.i64_lt_u,
i64_gt_s: self.i64_gt_s + other.i64_gt_s,
i64_gt_u: self.i64_gt_u + other.i64_gt_u,
i64_le_s: self.i64_le_s + other.i64_le_s,
i64_le_u: self.i64_le_u + other.i64_le_u,
i64_ge_s: self.i64_ge_s + other.i64_ge_s,
i64_ge_u: self.i64_ge_u + other.i64_ge_u,
f32_eq: self.f32_eq + other.f32_eq,
f32_ne: self.f32_ne + other.f32_ne,
f32_lt: self.f32_lt + other.f32_lt,
f32_gt: self.f32_gt + other.f32_gt,
f32_le: self.f32_le + other.f32_le,
f32_ge: self.f32_ge + other.f32_ge,
f64_eq: self.f64_eq + other.f64_eq,
f64_ne: self.f64_ne + other.f64_ne,
f64_lt: self.f64_lt + other.f64_lt,
f64_gt: self.f64_gt + other.f64_gt,
f64_le: self.f64_le + other.f64_le,
f64_ge: self.f64_ge + other.f64_ge,
i32_clz: self.i32_clz + other.i32_clz,
i32_ctz: self.i32_ctz + other.i32_ctz,
i32_popcnt: self.i32_popcnt + other.i32_popcnt,
i32_add: self.i32_add + other.i32_add,
i32_sub: self.i32_sub + other.i32_sub,
i32_mul: self.i32_mul + other.i32_mul,
i32_div_s: self.i32_div_s + other.i32_div_s,
i32_div_u: self.i32_div_u + other.i32_div_u,
i32_rem_s: self.i32_rem_s + other.i32_rem_s,
i32_rem_u: self.i32_rem_u + other.i32_rem_u,
i32_and: self.i32_and + other.i32_and,
i32_or: self.i32_or + other.i32_or,
i32_xor: self.i32_xor + other.i32_xor,
i32_shl: self.i32_shl + other.i32_shl,
i32_shr_s: self.i32_shr_s + other.i32_shr_s,
i32_shr_u: self.i32_shr_u + other.i32_shr_u,
i32_rotl: self.i32_rotl + other.i32_rotl,
i32_rotr: self.i32_rotr + other.i32_rotr,
i64_clz: self.i64_clz + other.i64_clz,
i64_ctz: self.i64_ctz + other.i64_ctz,
i64_popcnt: self.i64_popcnt + other.i64_popcnt,
i64_add: self.i64_add + other.i64_add,
i64_sub: self.i64_sub + other.i64_sub,
i64_mul: self.i64_mul + other.i64_mul,
i64_div_s: self.i64_div_s + other.i64_div_s,
i64_div_u: self.i64_div_u + other.i64_div_u,
i64_rem_s: self.i64_rem_s + other.i64_rem_s,
i64_rem_u: self.i64_rem_u + other.i64_rem_u,
i64_and: self.i64_and + other.i64_and,
i64_or: self.i64_or + other.i64_or,
i64_xor: self.i64_xor + other.i64_xor,
i64_shl: self.i64_shl + other.i64_shl,
i64_shr_s: self.i64_shr_s + other.i64_shr_s,
i64_shr_u: self.i64_shr_u + other.i64_shr_u,
i64_rotl: self.i64_rotl + other.i64_rotl,
i64_rotr: self.i64_rotr + other.i64_rotr,
f32_abs: self.f32_abs + other.f32_abs,
f32_neg: self.f32_neg + other.f32_neg,
f32_ceil: self.f32_ceil + other.f32_ceil,
f32_floor: self.f32_floor + other.f32_floor,
f32_trunc: self.f32_trunc + other.f32_trunc,
f32_nearest: self.f32_nearest + other.f32_nearest,
f32_sqrt: self.f32_sqrt + other.f32_sqrt,
f32_add: self.f32_add + other.f32_add,
f32_sub: self.f32_sub + other.f32_sub,
f32_mul: self.f32_mul + other.f32_mul,
f32_div: self.f32_div + other.f32_div,
f32_min: self.f32_min + other.f32_min,
f32_max: self.f32_max + other.f32_max,
f32_copysign: self.f32_copysign + other.f32_copysign,
f64_abs: self.f64_abs + other.f64_abs,
f64_neg: self.f64_neg + other.f64_neg,
f64_ceil: self.f64_ceil + other.f64_ceil,
f64_floor: self.f64_floor + other.f64_floor,
f64_trunc: self.f64_trunc + other.f64_trunc,
f64_nearest: self.f64_nearest + other.f64_nearest,
f64_sqrt: self.f64_sqrt + other.f64_sqrt,
f64_add: self.f64_add + other.f64_add,
f64_sub: self.f64_sub + other.f64_sub,
f64_mul: self.f64_mul + other.f64_mul,
f64_div: self.f64_div + other.f64_div,
f64_min: self.f64_min + other.f64_min,
f64_max: self.f64_max + other.f64_max,
f64_copysign: self.f64_copysign + other.f64_copysign,
i32_wrap_i64: self.i32_wrap_i64 + other.i32_wrap_i64,
i32_trunc_f32s: self.i32_trunc_f32s + other.i32_trunc_f32s,
i32_trunc_f32u: self.i32_trunc_f32u + other.i32_trunc_f32u,
i32_trunc_f64s: self.i32_trunc_f64s + other.i32_trunc_f64s,
i32_trunc_f64u: self.i32_trunc_f64u + other.i32_trunc_f64u,
i64_extend_i32s: self.i64_extend_i32s + other.i64_extend_i32s,
i64_extend_i32u: self.i64_extend_i32u + other.i64_extend_i32u,
i64_trunc_f32s: self.i64_trunc_f32s + other.i64_trunc_f32s,
i64_trunc_f32u: self.i64_trunc_f32u + other.i64_trunc_f32u,
i64_trunc_f64s: self.i64_trunc_f64s + other.i64_trunc_f64s,
i64_trunc_f64u: self.i64_trunc_f64u + other.i64_trunc_f64u,
f32_convert_i32s: self.f32_convert_i32s + other.f32_convert_i32s,
f32_convert_i32u: self.f32_convert_i32u + other.f32_convert_i32u,
f32_convert_i64s: self.f32_convert_i64s + other.f32_convert_i64s,
f32_convert_i64u: self.f32_convert_i64u + other.f32_convert_i64u,
f32_demote_f64: self.f32_demote_f64 + other.f32_demote_f64,
f64_convert_i32s: self.f64_convert_i32s + other.f64_convert_i32s,
f64_convert_i32u: self.f64_convert_i32u + other.f64_convert_i32u,
f64_convert_i64s: self.f64_convert_i64s + other.f64_convert_i64s,
f64_convert_i64u: self.f64_convert_i64u + other.f64_convert_i64u,
f64_promote_f32: self.f64_promote_f32 + other.f64_promote_f32,
i32_extend8s: self.i32_extend8s + other.i32_extend8s,
i32_extend16s: self.i32_extend16s + other.i32_extend16s,
i64_extend8s: self.i64_extend8s + other.i64_extend8s,
i64_extend16s: self.i64_extend16s + other.i64_extend16s,
i64_extend32s: self.i64_extend32s + other.i64_extend32s,
i32_trunc_sat_f32s: self.i32_trunc_sat_f32s + other.i32_trunc_sat_f32s,
i32_trunc_sat_f32u: self.i32_trunc_sat_f32u + other.i32_trunc_sat_f32u,
i32_trunc_sat_f64s: self.i32_trunc_sat_f64s + other.i32_trunc_sat_f64s,
i32_trunc_sat_f64u: self.i32_trunc_sat_f64u + other.i32_trunc_sat_f64u,
i64_trunc_sat_f32s: self.i64_trunc_sat_f32s + other.i64_trunc_sat_f32s,
i64_trunc_sat_f32u: self.i64_trunc_sat_f32u + other.i64_trunc_sat_f32u,
i64_trunc_sat_f64s: self.i64_trunc_sat_f64s + other.i64_trunc_sat_f64s,
i64_trunc_sat_f64u: self.i64_trunc_sat_f64u + other.i64_trunc_sat_f64u,
i32_reinterpret_f32: self.i32_reinterpret_f32 + other.i32_reinterpret_f32,
i64_reinterpret_f64: self.i64_reinterpret_f64 + other.i64_reinterpret_f64,
f32_reinterpret_i32: self.f32_reinterpret_i32 + other.f32_reinterpret_i32,
f64_reinterpret_i64: self.f64_reinterpret_i64 + other.f64_reinterpret_i64,
br_table: self.br_table + other.br_table,
unreachable_opcode: self.unreachable_opcode + other.unreachable_opcode,
local_tee: self.local_tee + other.local_tee,
typed_select: self.typed_select + other.typed_select,
return_call: self.return_call + other.return_call,
return_call_indirect: self.return_call_indirect + other.return_call_indirect,
return_call_ref: self.return_call_ref + other.return_call_ref,
v128_const: self.v128_const + other.v128_const,
i8x16_splat: self.i8x16_splat + other.i8x16_splat,
i16x8_splat: self.i16x8_splat + other.i16x8_splat,
i32x4_splat: self.i32x4_splat + other.i32x4_splat,
i64x2_splat: self.i64x2_splat + other.i64x2_splat,
f32x4_splat: self.f32x4_splat + other.f32x4_splat,
f64x2_splat: self.f64x2_splat + other.f64x2_splat,
i8x16_extract_lane_s: self.i8x16_extract_lane_s + other.i8x16_extract_lane_s,
i8x16_extract_lane_u: self.i8x16_extract_lane_u + other.i8x16_extract_lane_u,
i8x16_replace_lane: self.i8x16_replace_lane + other.i8x16_replace_lane,
i16x8_extract_lane_s: self.i16x8_extract_lane_s + other.i16x8_extract_lane_s,
i16x8_extract_lane_u: self.i16x8_extract_lane_u + other.i16x8_extract_lane_u,
i16x8_replace_lane: self.i16x8_replace_lane + other.i16x8_replace_lane,
i32x4_extract_lane: self.i32x4_extract_lane + other.i32x4_extract_lane,
i32x4_replace_lane: self.i32x4_replace_lane + other.i32x4_replace_lane,
i64x2_extract_lane: self.i64x2_extract_lane + other.i64x2_extract_lane,
i64x2_replace_lane: self.i64x2_replace_lane + other.i64x2_replace_lane,
f32x4_extract_lane: self.f32x4_extract_lane + other.f32x4_extract_lane,
f32x4_replace_lane: self.f32x4_replace_lane + other.f32x4_replace_lane,
f64x2_extract_lane: self.f64x2_extract_lane + other.f64x2_extract_lane,
f64x2_replace_lane: self.f64x2_replace_lane + other.f64x2_replace_lane,
v128_not: self.v128_not + other.v128_not,
v128_and: self.v128_and + other.v128_and,
v128_andnot: self.v128_andnot + other.v128_andnot,
v128_or: self.v128_or + other.v128_or,
v128_xor: self.v128_xor + other.v128_xor,
v128_bitselect: self.v128_bitselect + other.v128_bitselect,
v128_any_true: self.v128_any_true + other.v128_any_true,
i8x16_eq: self.i8x16_eq + other.i8x16_eq,
i8x16_ne: self.i8x16_ne + other.i8x16_ne,
i8x16_lt_s: self.i8x16_lt_s + other.i8x16_lt_s,
i8x16_lt_u: self.i8x16_lt_u + other.i8x16_lt_u,
i8x16_gt_s: self.i8x16_gt_s + other.i8x16_gt_s,
i8x16_gt_u: self.i8x16_gt_u + other.i8x16_gt_u,
i8x16_le_s: self.i8x16_le_s + other.i8x16_le_s,
i8x16_le_u: self.i8x16_le_u + other.i8x16_le_u,
i8x16_ge_s: self.i8x16_ge_s + other.i8x16_ge_s,
i8x16_ge_u: self.i8x16_ge_u + other.i8x16_ge_u,
i16x8_eq: self.i16x8_eq + other.i16x8_eq,
i16x8_ne: self.i16x8_ne + other.i16x8_ne,
i16x8_lt_s: self.i16x8_lt_s + other.i16x8_lt_s,
i16x8_lt_u: self.i16x8_lt_u + other.i16x8_lt_u,
i16x8_gt_s: self.i16x8_gt_s + other.i16x8_gt_s,
i16x8_gt_u: self.i16x8_gt_u + other.i16x8_gt_u,
i16x8_le_s: self.i16x8_le_s + other.i16x8_le_s,
i16x8_le_u: self.i16x8_le_u + other.i16x8_le_u,
i16x8_ge_s: self.i16x8_ge_s + other.i16x8_ge_s,
i16x8_ge_u: self.i16x8_ge_u + other.i16x8_ge_u,
i32x4_eq: self.i32x4_eq + other.i32x4_eq,
i32x4_ne: self.i32x4_ne + other.i32x4_ne,
i32x4_lt_s: self.i32x4_lt_s + other.i32x4_lt_s,
i32x4_lt_u: self.i32x4_lt_u + other.i32x4_lt_u,
i32x4_gt_s: self.i32x4_gt_s + other.i32x4_gt_s,
i32x4_gt_u: self.i32x4_gt_u + other.i32x4_gt_u,
i32x4_le_s: self.i32x4_le_s + other.i32x4_le_s,
i32x4_le_u: self.i32x4_le_u + other.i32x4_le_u,
i32x4_ge_s: self.i32x4_ge_s + other.i32x4_ge_s,
i32x4_ge_u: self.i32x4_ge_u + other.i32x4_ge_u,
i64x2_eq: self.i64x2_eq + other.i64x2_eq,
i64x2_ne: self.i64x2_ne + other.i64x2_ne,
i64x2_lt_s: self.i64x2_lt_s + other.i64x2_lt_s,
i64x2_gt_s: self.i64x2_gt_s + other.i64x2_gt_s,
i64x2_le_s: self.i64x2_le_s + other.i64x2_le_s,
f32x4_eq: self.f32x4_eq + other.f32x4_eq,
f32x4_ne: self.f32x4_ne + other.f32x4_ne,
f32x4_lt: self.f32x4_lt + other.f32x4_lt,
f32x4_gt: self.f32x4_gt + other.f32x4_gt,
f32x4_le: self.f32x4_le + other.f32x4_le,
f32x4_ge: self.f32x4_ge + other.f32x4_ge,
f64x2_eq: self.f64x2_eq + other.f64x2_eq,
f64x2_ne: self.f64x2_ne + other.f64x2_ne,
f64x2_lt: self.f64x2_lt + other.f64x2_lt,
f64x2_gt: self.f64x2_gt + other.f64x2_gt,
f64x2_le: self.f64x2_le + other.f64x2_le,
f64x2_ge: self.f64x2_ge + other.f64x2_ge,
i8x16_abs: self.i8x16_abs + other.i8x16_abs,
i8x16_neg: self.i8x16_neg + other.i8x16_neg,
i8x16_popcnt: self.i8x16_popcnt + other.i8x16_popcnt,
i8x16_all_true: self.i8x16_all_true + other.i8x16_all_true,
i8x16_bitmask: self.i8x16_bitmask + other.i8x16_bitmask,
i16x8_abs: self.i16x8_abs + other.i16x8_abs,
i16x8_neg: self.i16x8_neg + other.i16x8_neg,
i16x8_q15mulr_sat_s: self.i16x8_q15mulr_sat_s + other.i16x8_q15mulr_sat_s,
i16x8_all_true: self.i16x8_all_true + other.i16x8_all_true,
i16x8_bitmask: self.i16x8_bitmask + other.i16x8_bitmask,
i32x4_abs: self.i32x4_abs + other.i32x4_abs,
i32x4_neg: self.i32x4_neg + other.i32x4_neg,
i32x4_bitmask: self.i32x4_bitmask + other.i32x4_bitmask,
i64x2_abs: self.i64x2_abs + other.i64x2_abs,
i64x2_neg: self.i64x2_neg + other.i64x2_neg,
i64x2_all_true: self.i64x2_all_true + other.i64x2_all_true,
i8x16_add: self.i8x16_add + other.i8x16_add,
i8x16_add_sat_s: self.i8x16_add_sat_s + other.i8x16_add_sat_s,
i8x16_add_sat_u: self.i8x16_add_sat_u + other.i8x16_add_sat_u,
i8x16_sub: self.i8x16_sub + other.i8x16_sub,
i8x16_sub_sat_s: self.i8x16_sub_sat_s + other.i8x16_sub_sat_s,
i16x8_mul: self.i16x8_mul + other.i16x8_mul,
i8x16_shl: self.i8x16_shl + other.i8x16_shl,
i8x16_shr_s: self.i8x16_shr_s + other.i8x16_shr_s,
i8x16_shr_u: self.i8x16_shr_u + other.i8x16_shr_u,
i16x8_shl: self.i16x8_shl + other.i16x8_shl,
i16x8_shr_s: self.i16x8_shr_s + other.i16x8_shr_s,
i16x8_shr_u: self.i16x8_shr_u + other.i16x8_shr_u,
i32x4_shl: self.i32x4_shl + other.i32x4_shl,
i32x4_shr_s: self.i32x4_shr_s + other.i32x4_shr_s,
i32x4_shr_u: self.i32x4_shr_u + other.i32x4_shr_u,
i64x2_shl: self.i64x2_shl + other.i64x2_shl,
i64x2_shr_s: self.i64x2_shr_s + other.i64x2_shr_s,
i64x2_shr_u: self.i64x2_shr_u + other.i64x2_shr_u,
i64x2_ge_s: self.i64x2_ge_s + other.i64x2_ge_s,
i32x4_all_true: self.i32x4_all_true + other.i32x4_all_true,
i64x2_bitmask: self.i64x2_bitmask + other.i64x2_bitmask,
i8x16_sub_sat_u: self.i8x16_sub_sat_u + other.i8x16_sub_sat_u,
i8x16_min_s: self.i8x16_min_s + other.i8x16_min_s,
i8x16_min_u: self.i8x16_min_u + other.i8x16_min_u,
i8x16_max_s: self.i8x16_max_s + other.i8x16_max_s,
i8x16_max_u: self.i8x16_max_u + other.i8x16_max_u,
i8x16_avgr_u: self.i8x16_avgr_u + other.i8x16_avgr_u,
i16x8_add: self.i16x8_add + other.i16x8_add,
i16x8_add_sat_s: self.i16x8_add_sat_s + other.i16x8_add_sat_s,
i16x8_add_sat_u: self.i16x8_add_sat_u + other.i16x8_add_sat_u,
i16x8_sub: self.i16x8_sub + other.i16x8_sub,
i16x8_sub_sat_s: self.i16x8_sub_sat_s + other.i16x8_sub_sat_s,
i16x8_sub_sat_u: self.i16x8_sub_sat_u + other.i16x8_sub_sat_u,
i16x8_min_s: self.i16x8_min_s + other.i16x8_min_s,
i16x8_min_u: self.i16x8_min_u + other.i16x8_min_u,
i16x8_max_s: self.i16x8_max_s + other.i16x8_max_s,
i16x8_max_u: self.i16x8_max_u + other.i16x8_max_u,
i16x8_avgr_u: self.i16x8_avgr_u + other.i16x8_avgr_u,
i32x4_add: self.i32x4_add + other.i32x4_add,
i32x4_sub: self.i32x4_sub + other.i32x4_sub,
i32x4_mul: self.i32x4_mul + other.i32x4_mul,
i32x4_min_s: self.i32x4_min_s + other.i32x4_min_s,
i32x4_min_u: self.i32x4_min_u + other.i32x4_min_u,
i32x4_max_s: self.i32x4_max_s + other.i32x4_max_s,
i32x4_max_u: self.i32x4_max_u + other.i32x4_max_u,
i64x2_add: self.i64x2_add + other.i64x2_add,
i64x2_sub: self.i64x2_sub + other.i64x2_sub,
i64x2_mul: self.i64x2_mul + other.i64x2_mul,
f32x4_add: self.f32x4_add + other.f32x4_add,
f32x4_abs: self.f32x4_abs + other.f32x4_abs,
f32x4_neg: self.f32x4_neg + other.f32x4_neg,
f32x4_sqrt: self.f32x4_sqrt + other.f32x4_sqrt,
f32x4_sub: self.f32x4_sub + other.f32x4_sub,
f32x4_mul: self.f32x4_mul + other.f32x4_mul,
f32x4_div: self.f32x4_div + other.f32x4_div,
f32x4_min: self.f32x4_min + other.f32x4_min,
f32x4_max: self.f32x4_max + other.f32x4_max,
f32x4_pmin: self.f32x4_pmin + other.f32x4_pmin,
f32x4_pmax: self.f32x4_pmax + other.f32x4_pmax,
f64x2_add: self.f64x2_add + other.f64x2_add,
f64x2_abs: self.f64x2_abs + other.f64x2_abs,
f64x2_neg: self.f64x2_neg + other.f64x2_neg,
f64x2_sqrt: self.f64x2_sqrt + other.f64x2_sqrt,
f64x2_sub: self.f64x2_sub + other.f64x2_sub,
f64x2_mul: self.f64x2_mul + other.f64x2_mul,
f64x2_div: self.f64x2_div + other.f64x2_div,
f64x2_min: self.f64x2_min + other.f64x2_min,
f64x2_max: self.f64x2_max + other.f64x2_max,
f64x2_pmin: self.f64x2_pmin + other.f64x2_pmin,
f64x2_pmax: self.f64x2_pmax + other.f64x2_pmax,
f32x4_ceil: self.f32x4_ceil + other.f32x4_ceil,
f32x4_floor: self.f32x4_floor + other.f32x4_floor,
f32x4_trunc: self.f32x4_trunc + other.f32x4_trunc,
f32x4_nearest: self.f32x4_nearest + other.f32x4_nearest,
f64x2_ceil: self.f64x2_ceil + other.f64x2_ceil,
f64x2_floor: self.f64x2_floor + other.f64x2_floor,
f64x2_trunc: self.f64x2_trunc + other.f64x2_trunc,
f64x2_nearest: self.f64x2_nearest + other.f64x2_nearest,
v128_load8x8_s: self.v128_load8x8_s + other.v128_load8x8_s,
v128_load8x8_u: self.v128_load8x8_u + other.v128_load8x8_u,
v128_load16x4_s: self.v128_load16x4_s + other.v128_load16x4_s,
v128_load16x4_u: self.v128_load16x4_u + other.v128_load16x4_u,
v128_load32x2_s: self.v128_load32x2_s + other.v128_load32x2_s,
v128_load32x2_u: self.v128_load32x2_u + other.v128_load32x2_u,
v128_load8_splat: self.v128_load8_splat + other.v128_load8_splat,
v128_load16_splat: self.v128_load16_splat + other.v128_load16_splat,
v128_load32_splat: self.v128_load32_splat + other.v128_load32_splat,
v128_load64_splat: self.v128_load64_splat + other.v128_load64_splat,
v128_load8_lane: self.v128_load8_lane + other.v128_load8_lane,
v128_load16_lane: self.v128_load16_lane + other.v128_load16_lane,
v128_load32_lane: self.v128_load32_lane + other.v128_load32_lane,
v128_load64_lane: self.v128_load64_lane + other.v128_load64_lane,
v128_store8_lane: self.v128_store8_lane + other.v128_store8_lane,
v128_store16_lane: self.v128_store16_lane + other.v128_store16_lane,
v128_store32_lane: self.v128_store32_lane + other.v128_store32_lane,
v128_store64_lane: self.v128_store64_lane + other.v128_store64_lane,
v128_load32_zero: self.v128_load32_zero + other.v128_load32_zero,
v128_load64_zero: self.v128_load64_zero + other.v128_load64_zero,
i8x16_narrow_i16x8_u: self.i8x16_narrow_i16x8_u + other.i8x16_narrow_i16x8_u,
i16x8_narrow_i32x4_s: self.i16x8_narrow_i32x4_s + other.i16x8_narrow_i32x4_s,
i16x8_narrow_i32x4_u: self.i16x8_narrow_i32x4_u + other.i16x8_narrow_i32x4_u,
i16x8_extadd_pairwise_i8x16_s: self.i16x8_extadd_pairwise_i8x16_s +
other.i16x8_extadd_pairwise_i8x16_s,
i16x8_extadd_pairwise_i8x16_u: self.i16x8_extadd_pairwise_i8x16_u +
other.i16x8_extadd_pairwise_i8x16_u,
i32x4_extadd_pairwise_i16x8_s: self.i32x4_extadd_pairwise_i16x8_s +
other.i32x4_extadd_pairwise_i16x8_s,
i32x4_extadd_pairwise_i16x8_u: self.i32x4_extadd_pairwise_i16x8_u +
other.i32x4_extadd_pairwise_i16x8_u,
i16x8_extend_low_i8x16_s: self.i16x8_extend_low_i8x16_s +
other.i16x8_extend_low_i8x16_s,
i16x8_extend_high_i8x16_s: self.i16x8_extend_high_i8x16_s +
other.i16x8_extend_high_i8x16_s,
i16x8_extend_low_i8x16_u: self.i16x8_extend_low_i8x16_u +
other.i16x8_extend_low_i8x16_u,
i16x8_extend_high_i8x16_u: self.i16x8_extend_high_i8x16_u +
other.i16x8_extend_high_i8x16_u,
i32x4_extend_low_i16x8_s: self.i32x4_extend_low_i16x8_s +
other.i32x4_extend_low_i16x8_s,
i32x4_extend_high_i16x8_s: self.i32x4_extend_high_i16x8_s +
other.i32x4_extend_high_i16x8_s,
i32x4_extend_low_i16x8_u: self.i32x4_extend_low_i16x8_u +
other.i32x4_extend_low_i16x8_u,
i32x4_extend_high_i16x8_u: self.i32x4_extend_high_i16x8_u +
other.i32x4_extend_high_i16x8_u,
i64x2_extend_low_i32x4_s: self.i64x2_extend_low_i32x4_s +
other.i64x2_extend_low_i32x4_s,
i64x2_extend_high_i32x4_s: self.i64x2_extend_high_i32x4_s +
other.i64x2_extend_high_i32x4_s,
i64x2_extend_low_i32x4_u: self.i64x2_extend_low_i32x4_u +
other.i64x2_extend_low_i32x4_u,
i64x2_extend_high_i32x4_u: self.i64x2_extend_high_i32x4_u +
other.i64x2_extend_high_i32x4_u,
i16x8_extmul_low_i8x16_s: self.i16x8_extmul_low_i8x16_s +
other.i16x8_extmul_low_i8x16_s,
i16x8_extmul_high_i8x16_s: self.i16x8_extmul_high_i8x16_s +
other.i16x8_extmul_high_i8x16_s,
i16x8_extmul_low_i8x16_u: self.i16x8_extmul_low_i8x16_u +
other.i16x8_extmul_low_i8x16_u,
i16x8_extmul_high_i8x16_u: self.i16x8_extmul_high_i8x16_u +
other.i16x8_extmul_high_i8x16_u,
i32x4_extmul_low_i16x8_s: self.i32x4_extmul_low_i16x8_s +
other.i32x4_extmul_low_i16x8_s,
i32x4_extmul_high_i16x8_s: self.i32x4_extmul_high_i16x8_s +
other.i32x4_extmul_high_i16x8_s,
i32x4_extmul_low_i16x8_u: self.i32x4_extmul_low_i16x8_u +
other.i32x4_extmul_low_i16x8_u,
i32x4_extmul_high_i16x8_u: self.i32x4_extmul_high_i16x8_u +
other.i32x4_extmul_high_i16x8_u,
i64x2_extmul_low_i32x4_s: self.i64x2_extmul_low_i32x4_s +
other.i64x2_extmul_low_i32x4_s,
i64x2_extmul_high_i32x4_s: self.i64x2_extmul_high_i32x4_s +
other.i64x2_extmul_high_i32x4_s,
i64x2_extmul_low_i32x4_u: self.i64x2_extmul_low_i32x4_u +
other.i64x2_extmul_low_i32x4_u,
i64x2_extmul_high_i32x4_u: self.i64x2_extmul_high_i32x4_u +
other.i64x2_extmul_high_i32x4_u,
f64x2_promote_low_f32x4: self.f64x2_promote_low_f32x4 +
other.f64x2_promote_low_f32x4,
v128_load: self.v128_load + other.v128_load,
v128_store: self.v128_store + other.v128_store,
i8x16_shuffle: self.i8x16_shuffle + other.i8x16_shuffle,
i8x16_swizzle: self.i8x16_swizzle + other.i8x16_swizzle,
i8x16_narrow_i16x8_s: self.i8x16_narrow_i16x8_s + other.i8x16_narrow_i16x8_s,
i32x4_dot_i16x8_s: self.i32x4_dot_i16x8_s + other.i32x4_dot_i16x8_s,
f32x4_demote_f64x2_zero: self.f32x4_demote_f64x2_zero +
other.f32x4_demote_f64x2_zero,
i32x4_trunc_sat_f32x4_s: self.i32x4_trunc_sat_f32x4_s +
other.i32x4_trunc_sat_f32x4_s,
i32x4_trunc_sat_f32x4_u: self.i32x4_trunc_sat_f32x4_u +
other.i32x4_trunc_sat_f32x4_u,
f32x4_convert_i32x4_s: self.f32x4_convert_i32x4_s +
other.f32x4_convert_i32x4_s,
f32x4_convert_i32x4_u: self.f32x4_convert_i32x4_u +
other.f32x4_convert_i32x4_u,
i32x4_trunc_sat_f64x2_s_zero: self.i32x4_trunc_sat_f64x2_s_zero +
other.i32x4_trunc_sat_f64x2_s_zero,
i32x4_trunc_sat_f64x2_u_zero: self.i32x4_trunc_sat_f64x2_u_zero +
other.i32x4_trunc_sat_f64x2_u_zero,
f64x2_convert_low_i32x4_s: self.f64x2_convert_low_i32x4_s +
other.f64x2_convert_low_i32x4_s,
f64x2_convert_low_i32x4_u: self.f64x2_convert_low_i32x4_u +
other.f64x2_convert_low_i32x4_u,
i8x16_relaxed_swizzle: self.i8x16_relaxed_swizzle +
other.i8x16_relaxed_swizzle,
i32x4_relaxed_trunc_f32x4_s: self.i32x4_relaxed_trunc_f32x4_s +
other.i32x4_relaxed_trunc_f32x4_s,
i32x4_relaxed_trunc_f32x4_u: self.i32x4_relaxed_trunc_f32x4_u +
other.i32x4_relaxed_trunc_f32x4_u,
i32x4_relaxed_trunc_zero_f64x2_s: self.i32x4_relaxed_trunc_zero_f64x2_s +
other.i32x4_relaxed_trunc_zero_f64x2_s,
i32x4_relaxed_trunc_zero_f64x2_u: self.i32x4_relaxed_trunc_zero_f64x2_u +
other.i32x4_relaxed_trunc_zero_f64x2_u,
f32x4_relaxed_madd: self.f32x4_relaxed_madd + other.f32x4_relaxed_madd,
f32x4_relaxed_nmadd: self.f32x4_relaxed_nmadd + other.f32x4_relaxed_nmadd,
f64x2_relaxed_madd: self.f64x2_relaxed_madd + other.f64x2_relaxed_madd,
f64x2_relaxed_nmadd: self.f64x2_relaxed_nmadd + other.f64x2_relaxed_nmadd,
i8x16_relaxed_laneselect: self.i8x16_relaxed_laneselect +
other.i8x16_relaxed_laneselect,
i16x8_relaxed_laneselect: self.i16x8_relaxed_laneselect +
other.i16x8_relaxed_laneselect,
i32x4_relaxed_laneselect: self.i32x4_relaxed_laneselect +
other.i32x4_relaxed_laneselect,
i64x2_relaxed_laneselect: self.i64x2_relaxed_laneselect +
other.i64x2_relaxed_laneselect,
f32x4_relaxed_min: self.f32x4_relaxed_min + other.f32x4_relaxed_min,
f32x4_relaxed_max: self.f32x4_relaxed_max + other.f32x4_relaxed_max,
f64x2_relaxed_min: self.f64x2_relaxed_min + other.f64x2_relaxed_min,
f64x2_relaxed_max: self.f64x2_relaxed_max + other.f64x2_relaxed_max,
i16x8_relaxed_q15mulr_s: self.i16x8_relaxed_q15mulr_s +
other.i16x8_relaxed_q15mulr_s,
i16x8_relaxed_dot_i8x16_i7x16_s: self.i16x8_relaxed_dot_i8x16_i7x16_s +
other.i16x8_relaxed_dot_i8x16_i7x16_s,
i32x4_relaxed_dot_i8x16_i7x16_add_s: self.i32x4_relaxed_dot_i8x16_i7x16_add_s +
other.i32x4_relaxed_dot_i8x16_i7x16_add_s,
}
}
///|
pub impl Show for GenValidExactOpcodeCounts with fn output(self, logger) {
logger.write_string("GenValidExactOpcodeCounts {i32_const: ")
self.i32_const.output(logger)
logger.write_string(", i64_const: ")
self.i64_const.output(logger)
logger.write_string(", f32_const: ")
self.f32_const.output(logger)
logger.write_string(", f64_const: ")
self.f64_const.output(logger)
logger.write_string(", i32_add: ")
self.i32_add.output(logger)
logger.write_string(", i64_add: ")
self.i64_add.output(logger)
logger.write_string(", f32_add: ")
self.f32_add.output(logger)
logger.write_string(", f64_add: ")
self.f64_add.output(logger)
logger.write_string(", br_table: ")
self.br_table.output(logger)
logger.write_string(", unreachable_opcode: ")
self.unreachable_opcode.output(logger)
logger.write_string(", local_tee: ")
self.local_tee.output(logger)
logger.write_string(", typed_select: ")
self.typed_select.output(logger)
logger.write_string(", return_call: ")
self.return_call.output(logger)
logger.write_string(", return_call_indirect: ")
self.return_call_indirect.output(logger)
logger.write_string(", return_call_ref: ")
self.return_call_ref.output(logger)
logger.write_string(", v128_const: ")
self.v128_const.output(logger)
logger.write_string(", i8x16_splat: ")
self.i8x16_splat.output(logger)
logger.write_string(", i8x16_add: ")
self.i8x16_add.output(logger)
logger.write_string(", v128_load: ")
self.v128_load.output(logger)
logger.write_char('}')
}
///|
fn gen_valid_exact_opcode_counts_nonzero(
counts : GenValidExactOpcodeCounts,
) -> Bool {
counts != GenValidExactOpcodeCounts::empty()
}
///|
fn GenValidInstrFacts::empty() -> GenValidInstrFacts {
{
uses_ref_types: false,
uses_v128: false,
has_call: false,
has_call_indirect: false,
has_numeric_full_ops: false,
has_br_table: false,
has_payload_control_flow: false,
has_multivalue_control_flow: false,
has_standalone_unreachable: false,
has_local_tee: false,
has_typed_select: false,
has_tail_calls: false,
has_scalar_memory_widths: false,
has_nonzero_memarg: false,
has_memory_limit_variants: false,
has_basic_ref_instructions: false,
has_i31_extern_conversions: false,
has_simd_phase1: false,
has_simd_phase2: false,
has_simd_phase3: false,
has_atomics: false,
has_gc_constructors: false,
has_gc_accessors: false,
has_string_ops: false,
has_exception_try_table_matrix: false,
has_subtyping_topology: false,
has_rich_gc_field_plans: false,
has_shared_memories: false,
exact_opcode_counts: GenValidExactOpcodeCounts::empty(),
control_nodes: 0,
branch_ops: 0,
}
}
///|
fn gen_valid_bool_count(flag : Bool) -> Int32 {
if flag {
1
} else {
0
}
}
///|
fn gen_valid_clamp_non_negative(value : Int32) -> Int32 {
if value < 0 {
0
} else {
value
}
}
///|
fn gen_valid_min_int(left : Int32, right : Int32) -> Int32 {
if left < right {
left
} else {
right
}
}
///|
fn gen_valid_roll_percent_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
percent : Int32,
) -> Bool {
let bounded = if percent < 0 {
0
} else if percent > 100 {
100
} else {
percent
}
if bounded <= 0 {
false
} else if bounded >= 100 {
true
} else {
ctx.random_int_from(label, 100) < bounded
}
}
///|
fn GenValidContext::random_int_from(
self : GenValidContext,
label : GenValidRandomStreamLabel,
max : Int32,
) -> Int32 {
if max <= 0 {
return 0
}
if !self.use_named_streams {
return (self.rnd.next_int().reinterpret_as_uint() %
max.reinterpret_as_uint()).reinterpret_as_int()
}
let value = match label {
ModuleTopologyStream => self.module_topology_rnd.next_int()
TypeStream => self.type_rnd.next_int()
FuncStream => self.func_rnd.next_int()
BodyStream => self.body_rnd.next_int()
MemoryStream => self.memory_rnd.next_int()
TableStream => self.table_rnd.next_int()
DataStream => self.data_rnd.next_int()
ElemStream => self.elem_rnd.next_int()
GlobalStream => self.global_rnd.next_int()
TagStream => self.tag_rnd.next_int()
StartStream => self.start_rnd.next_int()
InvalidStrategyChoiceStream
| InvalidMutationChoiceStream
| TextMutationChoiceStream
| HarnessShufflingStream => self.rnd.next_int()
}
(value.reinterpret_as_uint() % max.reinterpret_as_uint()).reinterpret_as_int()
}
///|
fn GenValidContext::random_bool_from(
self : GenValidContext,
label : GenValidRandomStreamLabel,
) -> Bool {
self.random_int_from(label, 2) == 0
}
///|
fn gen_valid_ref_valtype_pool(
ctx : GenValidContext,
extra_ref_types : Array[ValType],
) -> Array[ValType] {
let refs : Array[ValType] = [ValType::funcref(), ValType::externref()]
// String references are intentionally tied to the richer const-expression
// surface for now. The Binaryen-oracle profiles keep that surface off and
// validate through wasm-tools --features all, which currently rejects
// stringref value types.
if ctx.config.features.allow_const_expr_variants {
refs.push(ValType::stringref())
}
if ctx.config.features.allow_tags {
refs.push(ValType::ref_null_exn())
}
refs.push(ValType::ref_type(RefType::abs(AbsHeapType::any())))
refs.push(ValType::ref_type(RefType::abs(AbsHeapType::eq())))
refs.push(ValType::ref_type(RefType::abs(AbsHeapType::i31())))
refs.push(ValType::ref_type(RefType::abs(AbsHeapType::struct_())))
refs.push(ValType::ref_type(RefType::abs(AbsHeapType::array())))
for vt in extra_ref_types {
refs.push(vt)
}
refs
}
///|
fn gen_valid_valtype_with_extra_refs_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
extra_ref_types : Array[ValType],
) -> ValType {
let scalar_choice_count = 4 +
gen_valid_bool_count(ctx.config.features.allow_v128)
let ref_pool = if ctx.config.features.allow_ref_types {
gen_valid_ref_valtype_pool(ctx, extra_ref_types)
} else {
[]
}
let choice = ctx.random_int_from(
label,
scalar_choice_count + ref_pool.length(),
)
if choice == 0 {
ValType::i32()
} else if choice == 1 {
ValType::i64()
} else if choice == 2 {
ValType::f32()
} else if choice == 3 {
ValType::f64()
} else if ctx.config.features.allow_v128 && choice == 4 {
ValType::v128()
} else if ref_pool.is_empty() {
ValType::i32()
} else {
ref_pool[choice - scalar_choice_count]
}
}
///|
pub fn gen_valid_valtype_with_extra_refs(
ctx : GenValidContext,
extra_ref_types : Array[ValType],
) -> ValType {
gen_valid_valtype_with_extra_refs_from(ctx, TypeStream, extra_ref_types)
}
///|
pub fn gen_valid_valtype(ctx : GenValidContext) -> ValType {
gen_valid_valtype_with_extra_refs(ctx, [])
}
///|
pub fn gen_valid_numtype(ctx : GenValidContext) -> NumType {
match ctx.random_int_from(TypeStream, 4) {
0 => NumType::i32()
1 => NumType::i64()
2 => NumType::f32()
_ => NumType::f64()
}
}
///|
pub enum GenValidConstExprUse {
GlobalInitializerConstExpr
DataOffsetConstExpr
ElementOffsetConstExpr
ElementPayloadConstExpr
TableInitializerConstExpr
} derive(Eq, Debug)
///|
pub enum GenValidConstExprOpFamily {
NumericConstExprOp
RefNullConstExprOp
RefFuncConstExprOp
ImportedImmutableGlobalGetConstExprOp
I31RefConstExprOp
GcConstructorConstExprOp
} derive(Eq, Debug)
///|
pub struct GenValidConstExprAllowedOps {
context : GenValidConstExprUse
allowed_ops : Array[GenValidConstExprOpFamily]
} derive(Eq, Debug)
///|
pub fn gen_valid_const_expr_allowed_op_matrix() -> Array[
GenValidConstExprAllowedOps,
] {
[
{
context: GlobalInitializerConstExpr,
allowed_ops: [
NumericConstExprOp,
RefNullConstExprOp,
RefFuncConstExprOp,
ImportedImmutableGlobalGetConstExprOp,
I31RefConstExprOp,
GcConstructorConstExprOp,
],
},
{
context: DataOffsetConstExpr,
allowed_ops: [NumericConstExprOp, ImportedImmutableGlobalGetConstExprOp],
},
{
context: ElementOffsetConstExpr,
allowed_ops: [NumericConstExprOp, ImportedImmutableGlobalGetConstExprOp],
},
{
context: ElementPayloadConstExpr,
allowed_ops: [
RefNullConstExprOp,
RefFuncConstExprOp,
ImportedImmutableGlobalGetConstExprOp,
I31RefConstExprOp,
GcConstructorConstExprOp,
],
},
{
context: TableInitializerConstExpr,
allowed_ops: [
RefNullConstExprOp,
RefFuncConstExprOp,
ImportedImmutableGlobalGetConstExprOp,
I31RefConstExprOp,
GcConstructorConstExprOp,
],
},
]
}
///|
pub struct GenValidConstExprObservedOps {
context : GenValidConstExprUse
observed_ops : Array[GenValidConstExprOpFamily]
} derive(Eq, Debug)
///|
fn gen_valid_const_expr_add_observed_op(
ops : Array[GenValidConstExprOpFamily],
op : GenValidConstExprOpFamily,
) -> Unit {
for existing in ops {
if existing == op {
return
}
}
ops.push(op)
}
///|
fn gen_valid_const_expr_observe(
rows : Array[GenValidConstExprObservedOps],
context : GenValidConstExprUse,
expr : Expr,
) -> Unit {
let mut target_ops : Array[GenValidConstExprOpFamily] = []
for row in rows {
if row.context == context {
target_ops = row.observed_ops
}
}
let Expr(instrs) = expr
let mut saw_numeric_const = false
let mut saw_ref_i31 = false
for instr in instrs {
match instr {
I32Const(_)
| I64Const(_)
| F32Const(_)
| F64Const(_)
| V128Const(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) =>
saw_numeric_const = true
RefNull(_) =>
gen_valid_const_expr_add_observed_op(target_ops, RefNullConstExprOp)
RefFunc(_) =>
gen_valid_const_expr_add_observed_op(target_ops, RefFuncConstExprOp)
GlobalGet(_) =>
gen_valid_const_expr_add_observed_op(
target_ops,
ImportedImmutableGlobalGetConstExprOp,
)
RefI31 => saw_ref_i31 = true
StructNew(_)
| StructNewDefault(_)
| StructNewDesc(_)
| StructNewDefaultDesc(_)
| ArrayNew(_)
| ArrayNewDefault(_)
| ArrayNewFixed(_, _) =>
gen_valid_const_expr_add_observed_op(
target_ops,
GcConstructorConstExprOp,
)
_ => ()
}
}
if saw_ref_i31 {
gen_valid_const_expr_add_observed_op(target_ops, I31RefConstExprOp)
} else if saw_numeric_const {
gen_valid_const_expr_add_observed_op(target_ops, NumericConstExprOp)
}
}
///|
pub fn gen_valid_const_expr_observed_op_matrix(
mod : Module,
) -> Array[GenValidConstExprObservedOps] {
let rows = gen_valid_const_expr_allowed_op_matrix().map(fn(row) {
{ context: row.context, observed_ops: [], }
})
match mod.table_sec {
Some(TableSec(tables)) =>
for table in tables {
let Table(_, init_opt) = table
match init_opt {
Some(expr) =>
gen_valid_const_expr_observe(rows, TableInitializerConstExpr, expr)
None => ()
}
}
None => ()
}
match mod.global_sec {
Some(GlobalSec(globals)) =>
for global in globals {
let Global(_, expr) = global
gen_valid_const_expr_observe(rows, GlobalInitializerConstExpr, expr)
}
None => ()
}
match mod.elem_sec {
Some(ElemSec(elems)) =>
for elem in elems {
let Elem(mode, kind) = elem
match mode {
Active(_, expr) =>
gen_valid_const_expr_observe(rows, ElementOffsetConstExpr, expr)
_ => ()
}
match kind {
FuncExprsElemKind(exprs) | TypedExprsElemKind(_, exprs) =>
for expr in exprs {
gen_valid_const_expr_observe(rows, ElementPayloadConstExpr, expr)
}
_ => ()
}
}
None => ()
}
match mod.data_sec {
Some(DataSec(datas)) =>
for data in datas {
let Data(mode, _) = data
match mode {
Active(_, expr) =>
gen_valid_const_expr_observe(rows, DataOffsetConstExpr, expr)
_ => ()
}
}
None => ()
}
rows
}
///|
priv struct GenValidConstExprContext {
allow_numeric_const : Bool
allow_ref_null : Bool
allow_ref_func : Bool
allow_imported_immutable_global_get : Bool
allow_ref_i31 : Bool
}
///|
fn GenValidConstExprContext::numeric_only() -> GenValidConstExprContext {
{
allow_numeric_const: true,
allow_ref_null: false,
allow_ref_func: false,
allow_imported_immutable_global_get: false,
allow_ref_i31: false,
}
}
///|
fn gen_valid_const_expr_context_for_use(
context_use : GenValidConstExprUse,
) -> GenValidConstExprContext {
match context_use {
GlobalInitializerConstExpr =>
{
..GenValidConstExprContext::numeric_only(),
allow_ref_null: true,
allow_ref_func: true,
allow_imported_immutable_global_get: true,
allow_ref_i31: true,
}
DataOffsetConstExpr =>
{
..GenValidConstExprContext::numeric_only(),
allow_imported_immutable_global_get: true,
}
ElementOffsetConstExpr =>
{
..GenValidConstExprContext::numeric_only(),
allow_imported_immutable_global_get: true,
}
ElementPayloadConstExpr =>
{
allow_numeric_const: false,
allow_ref_null: true,
allow_ref_func: true,
allow_imported_immutable_global_get: true,
allow_ref_i31: true,
}
TableInitializerConstExpr =>
{
allow_numeric_const: false,
allow_ref_null: true,
allow_ref_func: true,
allow_imported_immutable_global_get: true,
allow_ref_i31: true,
}
}
}
///|
fn gen_const_expr_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
vt : ValType,
) -> Expr {
gen_valid_const_expr_from_context(
ctx,
label,
vt,
{ ..GenValidConstExprContext::numeric_only(), allow_ref_null: true, },
[],
None,
)
}
///|
fn gen_const_instr_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
vt : ValType,
) -> Instruction {
match vt {
NumTypeValType(I32NumType) =>
Instruction::i32_const(I32(ctx.random_int_from(label, 1000)))
NumTypeValType(I64NumType) =>
Instruction::i64_const(I64(ctx.random_int_from(label, 1000).to_int64()))
NumTypeValType(F32NumType) =>
Instruction::f32_const(
F32(Float::from_double(ctx.random_int_from(label, 100).to_double())),
)
NumTypeValType(F64NumType) =>
Instruction::f64_const(F64(ctx.random_int_from(label, 100).to_double()))
VecTypeValType =>
Instruction::v128_const(
b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00',
b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00',
)
_ if vt == ValType::stringref() => Instruction::string_const(b"gen-valid")
RefTypeValType(rt) =>
if rt.is_exact() {
Instruction::ref_null_type(rt)
} else {
Instruction::ref_null(rt.get_heap_type())
}
BotValType => Instruction::unreachable_()
}
}
///|
fn gen_valid_const_expr_from_context(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
vt : ValType,
expr_context : GenValidConstExprContext,
imported_immutable_globals : Array[GlobalType],
ref_func_idx : FuncIdx?,
) -> Expr {
if expr_context.allow_imported_immutable_global_get {
match gen_matching_immutable_global_idx(imported_immutable_globals, vt) {
Some(idx) => return Expr::new([Instruction::global_get(idx)])
None => ()
}
}
if expr_context.allow_ref_func && vt == ValType::funcref() {
match ref_func_idx {
Some(func_idx) => return Expr::new([Instruction::ref_func(func_idx)])
None => ()
}
}
if expr_context.allow_ref_i31 &&
vt == ValType::ref_type(RefType::abs(AbsHeapType::i31())) {
return Expr::new([Instruction::i32_const(I32(31)), Instruction::ref_i31()])
}
match vt {
RefTypeValType(rt) if expr_context.allow_ref_null =>
return Expr::new([
if rt.is_exact() {
Instruction::ref_null_type(rt)
} else {
Instruction::ref_null(rt.get_heap_type())
},
])
_ => ()
}
if expr_context.allow_numeric_const {
Expr::new([gen_const_instr_from(ctx, label, vt)])
} else {
Expr::new([Instruction::unreachable_()])
}
}
///|
fn gen_const_instr(ctx : GenValidContext, vt : ValType) -> Instruction {
gen_const_instr_from(ctx, ModuleTopologyStream, vt)
}
///|
fn gen_result_types(
ctx : GenValidContext,
extra_ref_types~ : Array[ValType] = [],
) -> Array[ValType] {
let max_results = gen_valid_clamp_non_negative(ctx.config.max_results)
if max_results <= 0 || ctx.random_bool_from(TypeStream) {
[]
} else {
let result_count = 1 + ctx.random_int_from(TypeStream, max_results)
let results : Array[ValType] = []
for i = 0; i < result_count; i = i + 1 {
if i == 0 &&
!extra_ref_types.is_empty() &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 3) == 0
) {
results.push(
extra_ref_types[ctx.random_int_from(
TypeStream,
extra_ref_types.length(),
)],
)
} else {
results.push(gen_valid_valtype_with_extra_refs(ctx, extra_ref_types))
}
}
results
}
}
///|
fn gen_param_types(ctx : GenValidContext) -> Array[ValType] {
let force_i32_param = ctx.config ==
GenValidConfig::for_profile(SsaParamEntryProfile) ||
ctx.config == GenValidConfig::for_profile(SsaMergeParamEntryProfile) ||
ctx.config == GenValidConfig::for_profile(SsaTypedControlProfile)
let random_count = ctx.random_int_from(
TypeStream,
gen_valid_clamp_non_negative(ctx.config.max_params) + 1,
)
let count = if force_i32_param && random_count == 0 {
1
} else {
random_count
}
let params : Array[ValType] = []
for i = 0; i < count; i = i + 1 {
if force_i32_param && i == 0 {
params.push(ValType::i32())
} else {
params.push(gen_valid_valtype(ctx))
}
}
params
}
///|
fn gen_local_types(
ctx : GenValidContext,
extra_ref_types~ : Array[ValType] = [],
) -> Array[ValType] {
let count = ctx.random_int_from(
FuncStream,
gen_valid_clamp_non_negative(ctx.config.max_locals) + 1,
)
let locals : Array[ValType] = []
for i = 0; i < count; i = i + 1 {
if i == 0 &&
!extra_ref_types.is_empty() &&
ctx.random_int_from(FuncStream, 4) == 0 {
locals.push(
extra_ref_types[ctx.random_int_from(
FuncStream,
extra_ref_types.length(),
)],
)
} else {
locals.push(
gen_valid_valtype_with_extra_refs_from(ctx, FuncStream, extra_ref_types),
)
}
}
locals
}
///|
fn gen_valid_ensure_body_layout_locals(
ctx : GenValidContext,
locals : Array[ValType],
) -> Unit {
if ctx.config.mode == CoverageForced &&
ctx.config.features.allow_ssa_nomerge_body_generator {
let required_i32_prefix = 5
while locals.length() < required_i32_prefix {
locals.push(ValType::i32())
}
for i = 0; i < required_i32_prefix; i = i + 1 {
locals[i] = ValType::i32()
}
if ctx.config == GenValidConfig::for_profile(SsaDefaultRefProfile) {
if locals.length() == required_i32_prefix {
locals.push(ValType::anyref())
} else {
locals[required_i32_prefix] = ValType::anyref()
}
}
let mut has_i64 = false
let mut has_f32 = false
let mut has_f64 = false
for vt in locals {
if vt == ValType::i64() {
has_i64 = true
} else if vt == ValType::f32() {
has_f32 = true
} else if vt == ValType::f64() {
has_f64 = true
}
}
if !has_i64 {
locals.push(ValType::i64())
}
if !has_f32 {
locals.push(ValType::f32())
}
if !has_f64 {
locals.push(ValType::f64())
}
}
if ctx.config.mode == CoverageForced &&
gen_valid_is_coalesce_locals_family_config(ctx.config) {
let required = if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsLargeUnusedProfile) {
64
} else {
4
}
while locals.length() < required {
locals.push(ValType::i32())
}
for i = 0; i < required; i = i + 1 {
locals[i] = ValType::i32()
}
if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsExactTypesProfile) {
locals[1] = ValType::f64()
locals[3] = ValType::f64()
}
}
if ctx.config.mode == CoverageForced &&
ctx.config.features.allow_typed_body_generator {
locals.push(ValType::i32())
locals.push(ValType::i32())
locals.push(ValType::i64())
if gen_valid_is_control_heavy_config(ctx.config) {
locals.push(ValType::f32())
}
if ctx.config.features.allow_v128 {
locals.push(ValType::v128())
} else {
locals.push(ValType::f32())
}
if gen_valid_is_control_heavy_config(ctx.config) {
for i = 0; i < 24; i = i + 1 {
match i % 4 {
0 => locals.push(ValType::i32())
1 => locals.push(ValType::i64())
2 => locals.push(ValType::f32())
_ => locals.push(ValType::f64())
}
}
}
}
}
///|
fn gen_all_local_types(
params : Array[ValType],
locals : Array[ValType],
) -> Array[ValType] {
let out = params.copy()
for local_ty in locals {
out.push(local_ty)
}
out
}
///|
fn gen_valid_gc_type_plan_empty() -> GenValidGcTypePlan {
{
struct_type_idxs: [],
array_type_idxs: [],
array_const_expr_shapes: [],
concrete_ref_types: [],
exact_ref_types: [],
bulk_data_array_idx: None,
bulk_elem_array_idx: None,
bulk_elem_ref_type: None,
packed_struct_idx: None,
packed_i8_array_idx: None,
packed_i16_array_idx: None,
v128_array_idx: None,
descriptor_struct_idx: None,
descriptor_type_idx: None,
string_wtf16_array_idx: None,
string_utf8_array_idx: None,
rec_group_count: 0,
}
}
///|
fn gen_valid_gc_type_field_ref(type_idx : TypeIdx) -> ValType {
ValType::ref_type(RefType::new(true, HeapType::new(type_idx)))
}
///|
fn gen_valid_gc_type_exact_ref(type_idx : TypeIdx) -> ValType {
ValType::ref_type(RefType::new(true, HeapType::new(type_idx), exact=true))
}
///|
fn gen_valid_gc_type_register_array_const_expr_shape(
plan : GenValidGcTypePlan,
type_idx : TypeIdx,
elem_vt : ValType,
) -> Unit {
plan.array_const_expr_shapes.push({
type_idx,
elem_vt,
has_default: has_default(elem_vt),
})
}
///|
fn gen_valid_gc_type_defs(
ctx : GenValidContext,
next_type_idx : Int32,
remaining_type_budget : Int32,
) -> (Array[RecType], GenValidGcTypePlan) {
if !ctx.config.features.allow_ref_types || remaining_type_budget <= 0 {
return ([], gen_valid_gc_type_plan_empty())
}
if ctx.config.mode != CoverageForced &&
ctx.random_int_from(TypeStream, 3) != 0 {
return ([], gen_valid_gc_type_plan_empty())
}
let defs : Array[RecType] = []
let mut plan = gen_valid_gc_type_plan_empty()
// Keep oracle-oriented ref/GC plans inside the value-type surface accepted by
// the compare harness' wasm-tools validation. All-features/natural profiles
// still include stringref and exnref through their enabling feature surfaces.
if ctx.config.features.allow_const_expr_variants {
plan.concrete_ref_types.push(ValType::stringref())
}
if ctx.config.features.allow_tags {
plan.concrete_ref_types.push(ValType::ref_null_exn())
}
let mut type_idx_cursor = next_type_idx
let want_struct = ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 4) != 0
let want_array = remaining_type_budget - defs.length() > 0 &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 3) != 0
)
let want_packed_struct = remaining_type_budget - defs.length() > 0 &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 3) == 0
)
let want_packed_i8_array = remaining_type_budget - defs.length() > 0 &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 3) == 0
)
let want_packed_i16_array = remaining_type_budget - defs.length() > 0 &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 3) == 0
)
let want_v128_array = ctx.config.features.allow_v128 &&
ctx.config.mode == CoverageForced &&
remaining_type_budget - defs.length() > 0
let hso_descriptor_leaf = !ctx.config.features.allow_heap_store_optimization_body_generator ||
ctx.config.max_body_statements == 94
let want_descriptor_group = hso_descriptor_leaf &&
remaining_type_budget - defs.length() > 0 &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 3) == 0
)
let want_elem_array = remaining_type_budget - defs.length() > 0 &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 3) == 0
)
let want_string_wtf16_array = ctx.config.features.allow_const_expr_variants &&
remaining_type_budget - defs.length() > 0 &&
(ctx.config.mode == CoverageForced || ctx.random_bool_from(TypeStream))
let want_string_utf8_array = ctx.config.features.allow_const_expr_variants &&
remaining_type_budget - defs.length() > 0 &&
(
ctx.config.mode == CoverageForced ||
ctx.config.mode == Natural ||
ctx.random_bool_from(TypeStream)
)
let want_group = remaining_type_budget - defs.length() > 0 &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 4) == 0
)
if ctx.config.features.allow_subtyping_topology &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 5) == 0
) &&
remaining_type_budget - defs.length() >= 5 {
let base_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
let child_idx = TypeIdx::new((type_idx_cursor + 1).reinterpret_as_uint())
let grandchild_idx = TypeIdx::new(
(type_idx_cursor + 2).reinterpret_as_uint(),
)
defs.push(
RecType::group([
SubType::new(true, [], CompType::struct_([])),
SubType::new(false, [], CompType::struct_([])),
SubType::new(false, [child_idx], CompType::struct_([])),
]),
)
type_idx_cursor += 3
let cross_ref_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
defs.push(
RecType::new(SubType::new(false, [grandchild_idx], CompType::struct_([]))),
)
type_idx_cursor += 1
defs.push(
RecType::new(
SubType::comp_type(
CompType::struct_([
FieldType::new(
StorageType::val_type(gen_valid_gc_type_field_ref(cross_ref_idx)),
Const,
),
]),
),
),
)
type_idx_cursor += 1
plan = { ..plan, rec_group_count: plan.rec_group_count + 1, }
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(base_idx))
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(child_idx))
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(grandchild_idx))
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(cross_ref_idx))
}
if want_struct && defs.length() < remaining_type_budget {
let struct_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
let hso_shared = ctx.config.features.allow_heap_store_optimization_body_generator &&
ctx.config.max_body_statements == 97
let struct_comp_type = if hso_shared {
CompType::struct_([
FieldType::new(StorageType::val_type(ValType::i32()), Var),
FieldType::new(StorageType::val_type(ValType::i32()), Var),
])
} else {
CompType::struct_([
FieldType::new(StorageType::val_type(ValType::i32()), Var),
FieldType::new(
StorageType::val_type(
ValType::ref_type(RefType::abs(AbsHeapType::eq())),
),
Const,
),
])
}
defs.push(
RecType::new(
SubType::comp_type(
struct_comp_type,
metadata=TypeMetadata::new(shared=hso_shared),
),
),
)
plan.struct_type_idxs.push(struct_idx)
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(struct_idx))
type_idx_cursor += 1
}
if want_packed_struct && defs.length() < remaining_type_budget {
let packed_struct_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
defs.push(
RecType::new(
SubType::comp_type(
CompType::struct_([
FieldType::new(StorageType::pack_type(PackType::i8()), Const),
FieldType::new(StorageType::pack_type(PackType::i16()), Const),
]),
),
),
)
plan = { ..plan, packed_struct_idx: Some(packed_struct_idx), }
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(packed_struct_idx))
type_idx_cursor += 1
}
if want_array && defs.length() < remaining_type_budget {
let array_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
defs.push(
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::val_type(ValType::i32()), Var),
),
),
),
)
plan.array_type_idxs.push(array_idx)
gen_valid_gc_type_register_array_const_expr_shape(
plan,
array_idx,
ValType::i32(),
)
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(array_idx))
plan = { ..plan, bulk_data_array_idx: Some(array_idx), }
type_idx_cursor += 1
}
if want_packed_i8_array && defs.length() < remaining_type_budget {
let packed_i8_array_idx = TypeIdx::new(
type_idx_cursor.reinterpret_as_uint(),
)
defs.push(
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::pack_type(PackType::i8()), Var),
),
),
),
)
plan.array_type_idxs.push(packed_i8_array_idx)
gen_valid_gc_type_register_array_const_expr_shape(
plan,
packed_i8_array_idx,
ValType::i32(),
)
plan = { ..plan, packed_i8_array_idx: Some(packed_i8_array_idx), }
plan.concrete_ref_types.push(
gen_valid_gc_type_field_ref(packed_i8_array_idx),
)
type_idx_cursor += 1
}
if want_packed_i16_array && defs.length() < remaining_type_budget {
let packed_i16_array_idx = TypeIdx::new(
type_idx_cursor.reinterpret_as_uint(),
)
defs.push(
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::pack_type(PackType::i16()), Var),
),
),
),
)
plan.array_type_idxs.push(packed_i16_array_idx)
gen_valid_gc_type_register_array_const_expr_shape(
plan,
packed_i16_array_idx,
ValType::i32(),
)
plan = { ..plan, packed_i16_array_idx: Some(packed_i16_array_idx), }
plan.concrete_ref_types.push(
gen_valid_gc_type_field_ref(packed_i16_array_idx),
)
type_idx_cursor += 1
}
if want_v128_array && defs.length() < remaining_type_budget {
let v128_array_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
defs.push(
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::val_type(ValType::v128()), Var),
),
),
),
)
plan.array_type_idxs.push(v128_array_idx)
gen_valid_gc_type_register_array_const_expr_shape(
plan,
v128_array_idx,
ValType::v128(),
)
plan = { ..plan, v128_array_idx: Some(v128_array_idx), }
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(v128_array_idx))
type_idx_cursor += 1
}
if want_descriptor_group &&
remaining_type_budget - (type_idx_cursor - next_type_idx) >= 2 {
let described_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
let descriptor_idx = TypeIdx::new(
(type_idx_cursor + 1).reinterpret_as_uint(),
)
let described_struct_comp_type = if ctx.config.features.allow_heap_store_optimization_body_generator {
CompType::struct_([
FieldType::new(StorageType::val_type(ValType::i32()), Var),
FieldType::new(
StorageType::val_type(
ValType::ref_type(RefType::abs(AbsHeapType::eq())),
),
Const,
),
])
} else {
CompType::struct_([])
}
if remaining_type_budget - (type_idx_cursor - next_type_idx) >= 4 {
let leaf_described_idx = TypeIdx::new(
(type_idx_cursor + 2).reinterpret_as_uint(),
)
let leaf_descriptor_idx = TypeIdx::new(
(type_idx_cursor + 3).reinterpret_as_uint(),
)
defs.push(
RecType::group([
SubType::new(
false,
[],
described_struct_comp_type,
metadata=TypeMetadata::new(descriptor=Some(descriptor_idx)),
),
SubType::new(
false,
[],
CompType::struct_([]),
metadata=TypeMetadata::new(describes=Some(described_idx)),
),
SubType::new(
true,
[described_idx],
described_struct_comp_type,
metadata=TypeMetadata::new(descriptor=Some(leaf_descriptor_idx)),
),
SubType::new(
true,
[descriptor_idx],
CompType::struct_([]),
metadata=TypeMetadata::new(describes=Some(leaf_described_idx)),
),
]),
)
plan = {
..plan,
descriptor_struct_idx: Some(described_idx),
descriptor_type_idx: Some(descriptor_idx),
rec_group_count: plan.rec_group_count + 1,
}
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(described_idx))
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(descriptor_idx))
plan.concrete_ref_types.push(
gen_valid_gc_type_field_ref(leaf_described_idx),
)
plan.concrete_ref_types.push(
gen_valid_gc_type_field_ref(leaf_descriptor_idx),
)
plan.exact_ref_types.push(gen_valid_gc_type_exact_ref(described_idx))
plan.exact_ref_types.push(gen_valid_gc_type_exact_ref(descriptor_idx))
plan.exact_ref_types.push(gen_valid_gc_type_exact_ref(leaf_described_idx))
plan.exact_ref_types.push(
gen_valid_gc_type_exact_ref(leaf_descriptor_idx),
)
type_idx_cursor += 4
} else {
defs.push(
RecType::group([
SubType::comp_type(
described_struct_comp_type,
metadata=TypeMetadata::new(descriptor=Some(descriptor_idx)),
),
SubType::comp_type(
CompType::struct_([]),
metadata=TypeMetadata::new(describes=Some(described_idx)),
),
]),
)
plan = {
..plan,
descriptor_struct_idx: Some(described_idx),
descriptor_type_idx: Some(descriptor_idx),
rec_group_count: plan.rec_group_count + 1,
}
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(described_idx))
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(descriptor_idx))
plan.exact_ref_types.push(gen_valid_gc_type_exact_ref(described_idx))
plan.exact_ref_types.push(gen_valid_gc_type_exact_ref(descriptor_idx))
type_idx_cursor += 2
}
}
let want_mutual_struct_array_group = ctx.config.features.allow_subtyping_topology &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TypeStream, 4) == 0
) &&
remaining_type_budget - (type_idx_cursor - next_type_idx) >= 2
if want_mutual_struct_array_group {
let struct_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
let array_idx = TypeIdx::new((type_idx_cursor + 1).reinterpret_as_uint())
defs.push(
RecType::group([
SubType::comp_type(
CompType::struct_([
FieldType::new(
StorageType::val_type(
ValType::ref_type(RefType::new(true, HeapType::new(array_idx))),
),
Var,
),
]),
),
SubType::comp_type(
CompType::array(
FieldType::new(
StorageType::val_type(
ValType::ref_type(RefType::new(true, HeapType::new(struct_idx))),
),
Var,
),
),
),
]),
)
plan = { ..plan, rec_group_count: plan.rec_group_count + 1, }
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(struct_idx))
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(array_idx))
plan.exact_ref_types.push(gen_valid_gc_type_exact_ref(struct_idx))
plan.exact_ref_types.push(gen_valid_gc_type_exact_ref(array_idx))
type_idx_cursor += 2
}
if want_elem_array && defs.length() < remaining_type_budget {
let elem_array_idx = TypeIdx::new(type_idx_cursor.reinterpret_as_uint())
let elem_ref_type = match plan.descriptor_type_idx {
Some(descriptor_idx) => RefType::new(true, HeapType::new(descriptor_idx))
None => RefType::abs(AbsHeapType::eq())
}
defs.push(
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(
StorageType::val_type(ValType::ref_type(elem_ref_type)),
Var,
),
),
),
),
)
plan.array_type_idxs.push(elem_array_idx)
gen_valid_gc_type_register_array_const_expr_shape(
plan,
elem_array_idx,
ValType::ref_type(elem_ref_type),
)
plan.concrete_ref_types.push(gen_valid_gc_type_field_ref(elem_array_idx))
plan = {
..plan,
bulk_elem_array_idx: Some(elem_array_idx),
bulk_elem_ref_type: Some(elem_ref_type),
}
type_idx_cursor += 1
}
if want_string_wtf16_array && defs.length() < remaining_type_budget {
let string_wtf16_array_idx = TypeIdx::new(
type_idx_cursor.reinterpret_as_uint(),
)
defs.push(
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::pack_type(PackType::i16()), Var),
),
),
),
)
plan = { ..plan, string_wtf16_array_idx: Some(string_wtf16_array_idx), }
plan.array_type_idxs.push(string_wtf16_array_idx)
gen_valid_gc_type_register_array_const_expr_shape(
plan,
string_wtf16_array_idx,
ValType::i32(),
)
plan.concrete_ref_types.push(
gen_valid_gc_type_field_ref(string_wtf16_array_idx),
)
type_idx_cursor += 1
}
if want_string_utf8_array && defs.length() < remaining_type_budget {
let string_utf8_array_idx = TypeIdx::new(
type_idx_cursor.reinterpret_as_uint(),
)
defs.push(
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::pack_type(PackType::i8()), Var),
),
),
),
)
plan = { ..plan, string_utf8_array_idx: Some(string_utf8_array_idx), }
plan.array_type_idxs.push(string_utf8_array_idx)
gen_valid_gc_type_register_array_const_expr_shape(
plan,
string_utf8_array_idx,
ValType::i32(),
)
plan.concrete_ref_types.push(
gen_valid_gc_type_field_ref(string_utf8_array_idx),
)
type_idx_cursor += 1
}
if want_group && defs.length() < remaining_type_budget {
defs.push(
RecType::group([
SubType::comp_type(
CompType::struct_([
FieldType::new(StorageType::val_type(ValType::i64()), Const),
]),
),
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::val_type(ValType::i32()), Var),
),
),
]),
)
type_idx_cursor += 2
plan = { ..plan, rec_group_count: plan.rec_group_count + 1, }
}
(defs, plan)
}
///|
fn gen_matching_local_idx(
local_types : Array[ValType],
vt : ValType,
) -> LocalIdx? {
for i = 0; i < local_types.length(); i = i + 1 {
if local_types[i] == vt {
return Some(LocalIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_matching_high_local_idx(
local_types : Array[ValType],
vt : ValType,
min_index : Int32,
) -> LocalIdx? {
for i = min_index; i < local_types.length(); i = i + 1 {
if local_types[i] == vt {
return Some(LocalIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_matching_high_local_idx_except(
local_types : Array[ValType],
vt : ValType,
min_index : Int32,
excluded : LocalIdx,
) -> LocalIdx? {
for i = min_index; i < local_types.length(); i = i + 1 {
let idx = LocalIdx::new(i.reinterpret_as_uint())
if local_types[i] == vt && idx != excluded {
return Some(idx)
}
}
None
}
///|
fn gen_valid_contains_type_idx(
type_idxs : Array[TypeIdx],
target : TypeIdx,
) -> Bool {
for type_idx in type_idxs {
if type_idx == target {
return true
}
}
false
}
///|
fn gen_valid_array_const_expr_shape_for_type_idx(
gc_type_plan : GenValidGcTypePlan,
target : TypeIdx,
) -> GenValidArrayConstExprShape? {
for shape in gc_type_plan.array_const_expr_shapes {
if shape.type_idx == target {
return Some(shape)
}
}
None
}
///|
fn gen_valid_array_const_expr_shape_for_ref_type(
gc_type_plan : GenValidGcTypePlan,
rt : RefType,
) -> GenValidArrayConstExprShape? {
match rt {
HeapTypeRefType(_, _, HeapType(type_idx)) =>
gen_valid_array_const_expr_shape_for_type_idx(gc_type_plan, type_idx)
_ => None
}
}
///|
fn gen_valid_first_array_const_expr_shape(
gc_type_plan : GenValidGcTypePlan,
) -> GenValidArrayConstExprShape? {
if gc_type_plan.array_const_expr_shapes.is_empty() {
None
} else {
Some(gc_type_plan.array_const_expr_shapes[0])
}
}
///|
fn gen_valid_v128_array_const_expr_shape(
gc_type_plan : GenValidGcTypePlan,
) -> GenValidArrayConstExprShape? {
match gc_type_plan.v128_array_idx {
Some(type_idx) =>
gen_valid_array_const_expr_shape_for_type_idx(gc_type_plan, type_idx)
None => None
}
}
///|
fn gen_valid_array_ref_type_from_shape(
shape : GenValidArrayConstExprShape,
) -> RefType {
RefType::new(true, HeapType::new(shape.type_idx))
}
///|
fn gen_valid_array_const_expr_from_shape(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
shape : GenValidArrayConstExprShape,
kind : GenValidArrayConstExprKind,
) -> Expr {
match kind {
ArrayNewConstExpr =>
Expr::new([
gen_const_instr_from(ctx, label, shape.elem_vt),
Instruction::i32_const(I32(1)),
Instruction::array_new(shape.type_idx),
])
ArrayNewDefaultConstExpr if shape.has_default =>
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::array_new_default(shape.type_idx),
])
ArrayNewDefaultConstExpr =>
Expr::new([Instruction::array_new_fixed(shape.type_idx, U32::new(0U))])
ArrayNewFixedConstExpr =>
Expr::new([Instruction::array_new_fixed(shape.type_idx, U32::new(0U))])
}
}
///|
fn gen_valid_callable_by_idx(
funcs : Array[GenValidFuncSig],
func_idx : FuncIdx,
) -> GenValidFuncSig? {
for func in funcs {
if func.idx == func_idx {
return Some(func)
}
}
None
}
///|
priv struct GenValidFuncSig {
idx : FuncIdx
type_idx : TypeIdx
params : Array[ValType]
results : Array[ValType]
}
///|
priv struct GenValidImportPlan {
func_count : Int32
table_count : Int32
mem_count : Int32
global_count : Int32
tag_count : Int32
}
///|
priv enum GenValidArrayConstExprKind {
ArrayNewConstExpr
ArrayNewDefaultConstExpr
ArrayNewFixedConstExpr
}
///|
priv struct GenValidArrayConstExprShape {
type_idx : TypeIdx
elem_vt : ValType
has_default : Bool
}
///|
priv struct GenValidGcTypePlan {
struct_type_idxs : Array[TypeIdx]
array_type_idxs : Array[TypeIdx]
array_const_expr_shapes : Array[GenValidArrayConstExprShape]
concrete_ref_types : Array[ValType]
exact_ref_types : Array[ValType]
bulk_data_array_idx : TypeIdx?
bulk_elem_array_idx : TypeIdx?
bulk_elem_ref_type : RefType?
packed_struct_idx : TypeIdx?
packed_i8_array_idx : TypeIdx?
packed_i16_array_idx : TypeIdx?
v128_array_idx : TypeIdx?
descriptor_struct_idx : TypeIdx?
descriptor_type_idx : TypeIdx?
string_wtf16_array_idx : TypeIdx?
string_utf8_array_idx : TypeIdx?
rec_group_count : Int32
}
///|
priv struct GenValidBodyEnv {
local_types : Array[ValType]
globals : Array[GlobalType]
tables : Array[TableType]
mems : Array[MemType]
tags : Array[TagType]
funcs : Array[GenValidFuncSig]
return_types : Array[ValType]
data_idxs : Array[DataIdx]
passive_elem_idxs : Array[ElemIdx]
passive_elem_ref_types : Array[RefType]
bulk_elem_seed_idx : ElemIdx?
gc_type_plan : GenValidGcTypePlan
declared_ref_func_idx : FuncIdx?
current_func_idx : FuncIdx?
depth_left : Int32
label_depth : Int32
}
///|
fn gen_matching_global_idx(
globals : Array[GlobalType],
vt : ValType,
mutable_only~ : Bool = false,
) -> GlobalIdx? {
for i = 0; i < globals.length(); i = i + 1 {
let GlobalType(global_vt, is_mut) = globals[i]
if global_vt == vt && (!mutable_only || is_mut) {
return Some(GlobalIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_matching_immutable_global_idx(
globals : Array[GlobalType],
vt : ValType,
) -> GlobalIdx? {
for i = 0; i < globals.length(); i = i + 1 {
let GlobalType(global_vt, is_mut) = globals[i]
if global_vt == vt && !is_mut {
return Some(GlobalIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_valid_const_expr_for_global(
ctx : GenValidContext,
vt : ValType,
prior_globals : Array[GlobalType],
func_idx : FuncIdx,
gc_type_plan : GenValidGcTypePlan,
) -> Expr {
if ctx.config.features.allow_const_expr_variants {
match gen_matching_immutable_global_idx(prior_globals, vt) {
Some(_) if vt == ValType::i32() &&
(
ctx.config.mode == CoverageForced ||
ctx.random_bool_from(GlobalStream)
) =>
return gen_valid_const_expr_from_context(
ctx,
GlobalStream,
vt,
{
..GenValidConstExprContext::numeric_only(),
allow_imported_immutable_global_get: true,
},
prior_globals,
None,
)
_ => ()
}
if vt == ValType::funcref() &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(GlobalStream, 4) == 0
) {
return gen_valid_const_expr_from_context(
ctx,
GlobalStream,
vt,
{ ..GenValidConstExprContext::numeric_only(), allow_ref_func: true, },
[],
Some(func_idx),
)
}
if vt == ValType::ref_type(RefType::abs(AbsHeapType::i31())) &&
ctx.config.mode == CoverageForced {
return gen_valid_const_expr_from_context(
ctx,
GlobalStream,
vt,
{ ..GenValidConstExprContext::numeric_only(), allow_ref_i31: true, },
[],
None,
)
}
match
(vt, gc_type_plan.descriptor_struct_idx, gc_type_plan.descriptor_type_idx) {
(
RefTypeValType(HeapTypeRefType(false, true, HeapType(type_idx))),
Some(described_idx),
Some(descriptor_idx),
) if type_idx == described_idx => {
let descriptor_vt = ValType::ref_type(
RefType::new(true, HeapType::new(descriptor_idx), exact=true),
)
match gen_matching_immutable_global_idx(prior_globals, descriptor_vt) {
Some(global_idx) =>
return Expr::new([
Instruction::global_get(global_idx),
Instruction::struct_new_default_desc(described_idx),
])
None => ()
}
}
_ => ()
}
match vt {
RefTypeValType(HeapTypeRefType(true, _, HeapType(type_idx))) =>
if gen_valid_contains_type_idx(gc_type_plan.struct_type_idxs, type_idx) &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(GlobalStream, 4) == 0
) {
return Expr::new([Instruction::struct_new_default(type_idx)])
}
_ => ()
}
match (vt, gen_matching_immutable_global_idx(prior_globals, vt)) {
(RefTypeValType(HeapTypeRefType(_, _, HeapType(_))), _) => ()
(_, Some(_)) if ctx.config.mode == CoverageForced ||
ctx.random_bool_from(GlobalStream) =>
return gen_valid_const_expr_from_context(
ctx,
GlobalStream,
vt,
{
..GenValidConstExprContext::numeric_only(),
allow_imported_immutable_global_get: true,
},
prior_globals,
None,
)
_ => ()
}
}
gen_const_expr_from(ctx, GlobalStream, vt)
}
///|
fn gen_valid_memarg() -> MemArg {
MemArg::new(U32(0), None, U64(0))
}
///|
fn gen_valid_memarg_varied(align_pow : UInt32, offset : UInt64) -> MemArg {
MemArg::new(U32(align_pow), None, U64(offset))
}
///|
fn gen_valid_simd_memarg_varied(
nonzero_mem_idx : MemIdx?,
align_pow : UInt32,
offset : UInt64,
) -> MemArg {
match nonzero_mem_idx {
Some(mem_idx) => MemArg::new(U32(align_pow), Some(mem_idx), U64(offset))
None => gen_valid_memarg_varied(align_pow, offset)
}
}
///|
fn gen_valid_memarg_for_mem(
mem_idx : MemIdx,
align_pow : UInt32,
offset : UInt64,
) -> MemArg {
MemArg::new(U32(align_pow), Some(mem_idx), U64(offset))
}
///|
fn gen_valid_body_env_child(
env : GenValidBodyEnv,
add_void_label~ : Bool = false,
) -> GenValidBodyEnv {
let next_label_depth = if add_void_label {
env.label_depth + 1
} else {
env.label_depth
}
{
..env,
depth_left: if env.depth_left > 0 {
env.depth_left - 1
} else {
0
},
label_depth: next_label_depth,
}
}
///|
fn gen_valid_body_stmt_count(
ctx : GenValidContext,
depth_left : Int32,
) -> Int32 {
let bounded = gen_valid_clamp_non_negative(ctx.config.max_body_statements)
let capped = if depth_left <= 0 {
gen_valid_min_int(2, bounded)
} else {
gen_valid_min_int(3, bounded)
}
1 + ctx.random_int_from(BodyStream, capped)
}
///|
fn gen_valid_append_call_args(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
params : Array[ValType],
) -> Unit {
let child_env = gen_valid_body_env_child(env)
for param in params {
append_value_instrs(out, ctx, param, child_env, prefer_local=true)
}
}
///|
fn gen_valid_append_call_result_drops(
out : Array[Instruction],
results : Array[ValType],
) -> Unit {
for _ in results {
out.push(Instruction::drop())
}
}
///|
fn gen_valid_append_direct_call(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
target : GenValidFuncSig,
) -> Unit {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::call(target.idx))
gen_valid_append_call_result_drops(out, target.results)
}
///|
fn gen_valid_func_idx_to_int(idx : FuncIdx) -> Int32 {
let FuncIdx(idx_u) = idx
idx_u.reinterpret_as_int()
}
///|
fn gen_valid_func_type_idx_from_ref_type(rt : RefType) -> TypeIdx? {
match rt {
HeapTypeRefType(_, _, HeapType(type_idx)) => Some(type_idx)
_ => None
}
}
///|
fn gen_valid_has_callable_with_result(
funcs : Array[GenValidFuncSig],
vt : ValType,
) -> Bool {
for func in funcs {
if func.results == [vt] {
return true
}
}
false
}
///|
fn gen_valid_declared_ref_callable_with_result(
funcs : Array[GenValidFuncSig],
declared_ref_func_idx : FuncIdx?,
vt : ValType,
) -> GenValidFuncSig? {
match declared_ref_func_idx {
Some(func_idx) =>
match gen_valid_callable_by_idx(funcs, func_idx) {
Some(target) if target.results == [vt] => Some(target)
_ => None
}
None => None
}
}
///|
fn gen_valid_declared_ref_callable_with_results(
funcs : Array[GenValidFuncSig],
declared_ref_func_idx : FuncIdx?,
results : Array[ValType],
) -> GenValidFuncSig? {
match declared_ref_func_idx {
Some(func_idx) =>
match gen_valid_callable_by_idx(funcs, func_idx) {
Some(target) if target.results == results => Some(target)
_ => None
}
None => None
}
}
///|
fn gen_valid_pick_callable_with_results(
ctx : GenValidContext,
funcs : Array[GenValidFuncSig],
results : Array[ValType],
) -> GenValidFuncSig? {
let matches : Array[GenValidFuncSig] = []
for func in funcs {
if func.results == results {
matches.push(func)
}
}
if matches.is_empty() {
None
} else {
Some(matches[ctx.random_int_from(BodyStream, matches.length())])
}
}
///|
fn gen_valid_pick_callable_with_result(
ctx : GenValidContext,
funcs : Array[GenValidFuncSig],
vt : ValType,
) -> GenValidFuncSig? {
let matches : Array[GenValidFuncSig] = []
for func in funcs {
if func.results == [vt] {
matches.push(func)
}
}
if matches.is_empty() {
None
} else {
Some(matches[ctx.random_int_from(BodyStream, matches.length())])
}
}
///|
fn gen_valid_pick_callable(
ctx : GenValidContext,
funcs : Array[GenValidFuncSig],
) -> GenValidFuncSig? {
if funcs.is_empty() {
None
} else {
Some(funcs[ctx.random_int_from(BodyStream, funcs.length())])
}
}
///|
fn gen_valid_append_table_ref_value(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
rt : RefType,
) -> Unit {
append_value_instrs(
out,
ctx,
ValType::ref_type(rt),
gen_valid_body_env_child(env),
prefer_local=false,
)
}
///|
fn gen_valid_pick_func_idx(
ctx : GenValidContext,
total_func_count : Int32,
preferred_idx : FuncIdx,
) -> FuncIdx {
if total_func_count <= 0 {
preferred_idx
} else if ctx.config.mode == CoverageForced ||
ctx.random_int_from(ElemStream, 3) == 0 {
preferred_idx
} else {
FuncIdx::new(
ctx.random_int_from(ElemStream, total_func_count).reinterpret_as_uint(),
)
}
}
///|
fn gen_valid_funcref_expr(ctx : GenValidContext, func_idx : FuncIdx) -> Expr {
if ctx.config.mode == CoverageForced ||
ctx.random_int_from(ElemStream, 4) != 0 {
Expr::new([Instruction::ref_func(func_idx)])
} else {
Expr::new([
Instruction::ref_null(RefType::abs(AbsHeapType::func()).get_heap_type()),
])
}
}
///|
fn gen_valid_elem_ref_expr(
ctx : GenValidContext,
rt : RefType,
func_idx~ : FuncIdx = FuncIdx::new(0U),
gc_type_plan~ : GenValidGcTypePlan = gen_valid_gc_type_plan_empty(),
array_kind~ : GenValidArrayConstExprKind? = None,
) -> Expr {
let vt = ValType::ref_type(rt)
if vt == ValType::funcref() {
gen_valid_funcref_expr(ctx, func_idx)
} else {
if ctx.config.features.allow_const_expr_variants {
match gen_valid_array_const_expr_shape_for_ref_type(gc_type_plan, rt) {
Some(shape) => {
let kind = match array_kind {
Some(k) => k
None =>
if ctx.config.mode == CoverageForced {
ArrayNewFixedConstExpr
} else if shape.has_default &&
ctx.random_int_from(ElemStream, 3) == 0 {
ArrayNewDefaultConstExpr
} else if ctx.random_bool_from(ElemStream) {
ArrayNewConstExpr
} else {
ArrayNewFixedConstExpr
}
}
return gen_valid_array_const_expr_from_shape(
ctx,
ElemStream,
shape,
kind,
)
}
None => ()
}
}
gen_valid_const_expr_from_context(
ctx,
ElemStream,
vt,
gen_valid_const_expr_context_for_use(ElementPayloadConstExpr),
[],
None,
)
}
}
///|
fn gen_valid_mem_type_is_i32(mt : MemType) -> Bool {
let MemType(lim, _) = mt
match lim {
I32Limits(_, _) => true
I64Limits(_) => false
}
}
///|
fn gen_valid_mem_type_addr_type(mt : MemType) -> ValType {
let MemType(lim, _) = mt
match lim {
I32Limits(_, _) => ValType::i32()
I64Limits(_) => ValType::i64()
}
}
///|
fn gen_valid_first_memory64_mem_idx(mems : Array[MemType]) -> MemIdx? {
for i = 0; i < mems.length(); i = i + 1 {
if !gen_valid_mem_type_is_i32(mems[i]) {
return Some(MemIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_valid_first_nonzero_i32_mem_idx(mems : Array[MemType]) -> MemIdx? {
for i = 1; i < mems.length(); i = i + 1 {
if gen_valid_mem_type_is_i32(mems[i]) {
return Some(MemIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_valid_append_memory_bulk_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Bool {
if env.mems.is_empty() {
return false
}
let mem_idx = MemIdx::new(0U)
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::memory_copy(mem_idx, mem_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(7)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::memory_fill(mem_idx))
if !env.data_idxs.is_empty() {
let data_idx = env.data_idxs[0]
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::memory_init(data_idx, mem_idx))
out.push(Instruction::data_drop(data_idx))
}
match gen_valid_first_nonzero_i32_mem_idx(env.mems) {
Some(nonzero_mem_idx) => {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::memory_copy(nonzero_mem_idx, mem_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(7)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::memory_fill(nonzero_mem_idx))
if !env.data_idxs.is_empty() {
let data_idx = if env.data_idxs.length() > 1 {
env.data_idxs[1]
} else {
env.data_idxs[0]
}
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::memory_init(data_idx, nonzero_mem_idx))
out.push(Instruction::data_drop(data_idx))
}
}
None => ()
}
ignore(ctx)
true
}
///|
fn gen_valid_append_scalar_memory_load_drop(
out : Array[Instruction],
load : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
out.push(load)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_scalar_memory_store(
out : Array[Instruction],
value : Instruction,
store : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
out.push(value)
out.push(store)
}
///|
fn gen_valid_append_nonzero_scalar_memory_ops(
out : Array[Instruction],
mem_idx : MemIdx,
) -> Unit {
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i32_load(gen_valid_memarg_for_mem(mem_idx, 2U, 88UL)),
)
gen_valid_append_scalar_memory_store(
out,
Instruction::i32_const(I32(10)),
Instruction::i32_store(gen_valid_memarg_for_mem(mem_idx, 2U, 92UL)),
)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i64_load8u(gen_valid_memarg_for_mem(mem_idx, 0U, 96UL)),
)
gen_valid_append_scalar_memory_store(
out,
Instruction::i64_const(I64(11L)),
Instruction::i64_store16(gen_valid_memarg_for_mem(mem_idx, 1U, 98UL)),
)
}
///|
fn gen_valid_append_scalar_memory_ops(out : Array[Instruction]) -> Unit {
let i32_load_ma = gen_valid_memarg_varied(2U, 4UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i32_load(i32_load_ma),
)
let i64_load_ma = gen_valid_memarg_varied(3U, 8UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i64_load(i64_load_ma),
)
let f32_load_ma = gen_valid_memarg_varied(2U, 12UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::f32_load(f32_load_ma),
)
let f64_load_ma = gen_valid_memarg_varied(3U, 16UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::f64_load(f64_load_ma),
)
let i32_load8s_ma = gen_valid_memarg_varied(0U, 20UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i32_load8s(i32_load8s_ma),
)
let i32_load8u_ma = gen_valid_memarg_varied(0U, 21UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i32_load8u(i32_load8u_ma),
)
let i32_load16s_ma = gen_valid_memarg_varied(1U, 22UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i32_load16s(i32_load16s_ma),
)
let i32_load16u_ma = gen_valid_memarg_varied(1U, 24UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i32_load16u(i32_load16u_ma),
)
let i64_load8s_ma = gen_valid_memarg_varied(0U, 26UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i64_load8s(i64_load8s_ma),
)
let i64_load8u_ma = gen_valid_memarg_varied(0U, 27UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i64_load8u(i64_load8u_ma),
)
let i64_load16s_ma = gen_valid_memarg_varied(1U, 28UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i64_load16s(i64_load16s_ma),
)
let i64_load16u_ma = gen_valid_memarg_varied(1U, 30UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i64_load16u(i64_load16u_ma),
)
let i64_load32s_ma = gen_valid_memarg_varied(2U, 32UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i64_load32s(i64_load32s_ma),
)
let i64_load32u_ma = gen_valid_memarg_varied(2U, 36UL)
gen_valid_append_scalar_memory_load_drop(
out,
Instruction::i64_load32u(i64_load32u_ma),
)
let i32_store_ma = gen_valid_memarg_varied(2U, 40UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::i32_const(I32(1)),
Instruction::i32_store(i32_store_ma),
)
let i64_store_ma = gen_valid_memarg_varied(3U, 48UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::i64_const(I64(2L)),
Instruction::i64_store(i64_store_ma),
)
let f32_store_ma = gen_valid_memarg_varied(2U, 56UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::f32_const(F32(Float::from_double(3.0))),
Instruction::f32_store(f32_store_ma),
)
let f64_store_ma = gen_valid_memarg_varied(3U, 64UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::f64_const(F64(4.0)),
Instruction::f64_store(f64_store_ma),
)
let i32_store8_ma = gen_valid_memarg_varied(0U, 72UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::i32_const(I32(5)),
Instruction::i32_store8(i32_store8_ma),
)
let i32_store16_ma = gen_valid_memarg_varied(1U, 74UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::i32_const(I32(6)),
Instruction::i32_store16(i32_store16_ma),
)
let i64_store8_ma = gen_valid_memarg_varied(0U, 76UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::i64_const(I64(7L)),
Instruction::i64_store8(i64_store8_ma),
)
let i64_store16_ma = gen_valid_memarg_varied(1U, 78UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::i64_const(I64(8L)),
Instruction::i64_store16(i64_store16_ma),
)
let i64_store32_ma = gen_valid_memarg_varied(2U, 80UL)
gen_valid_append_scalar_memory_store(
out,
Instruction::i64_const(I64(9L)),
Instruction::i64_store32(i64_store32_ma),
)
}
///|
fn gen_valid_first_nonzero_table_idx(tables : Array[TableType]) -> TableIdx? {
if tables.length() > 1 {
Some(TableIdx::new(1U))
} else {
None
}
}
///|
fn gen_valid_table_init_ref_types_compatible(
elem_rt : RefType,
table_rt : RefType,
) -> Bool {
elem_rt == table_rt ||
(
elem_rt.is_nullable() == table_rt.is_nullable() &&
elem_rt.get_heap_type() == table_rt.get_heap_type()
)
}
///|
fn gen_valid_nonzero_table_init_pair(
env : GenValidBodyEnv,
) -> (ElemIdx, TableIdx)? {
if env.passive_elem_idxs.is_empty() {
return None
}
for table_i = 1; table_i < env.tables.length(); table_i = table_i + 1 {
let TableType(table_rt, _) = env.tables[table_i]
for elem_i = 0; elem_i < env.passive_elem_idxs.length(); elem_i = elem_i + 1 {
if gen_valid_table_init_ref_types_compatible(
env.passive_elem_ref_types[elem_i],
table_rt,
) {
return Some(
(
env.passive_elem_idxs[elem_i],
TableIdx::new(table_i.reinterpret_as_uint()),
),
)
}
}
}
None
}
///|
fn gen_valid_append_nonzero_table_access_ops(
out : Array[Instruction],
env : GenValidBodyEnv,
table_idx : TableIdx,
) -> Unit {
let TableIdx(table_idx_u) = table_idx
let TableType(rt, _) = env.tables[table_idx_u.reinterpret_as_int()]
out.push(Instruction::table_size(table_idx))
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::ref_null(rt.get_heap_type()))
out.push(Instruction::table_set(table_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_get(table_idx))
out.push(Instruction::drop())
out.push(Instruction::ref_null(rt.get_heap_type()))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::table_grow(table_idx))
out.push(Instruction::drop())
}
///|
fn gen_valid_append_table_bulk_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Bool {
if env.tables.is_empty() {
return false
}
let table_idx = TableIdx::new(0U)
let TableType(rt, _) = env.tables[0]
out.push(Instruction::i32_const(I32(0)))
gen_valid_append_table_ref_value(out, ctx, env, rt)
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_fill(table_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_copy(table_idx, table_idx))
if !env.passive_elem_idxs.is_empty() {
let elem_idx = env.passive_elem_idxs[0]
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_init(elem_idx, table_idx))
out.push(Instruction::elem_drop(elem_idx))
}
match gen_valid_first_nonzero_table_idx(env.tables) {
Some(nonzero_table_idx) => {
let TableIdx(nonzero_table_idx_u) = nonzero_table_idx
let TableType(nonzero_rt, _) = env.tables[nonzero_table_idx_u.reinterpret_as_int()]
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::ref_null(nonzero_rt.get_heap_type()))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_fill(nonzero_table_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_copy(nonzero_table_idx, nonzero_table_idx))
}
None => ()
}
match gen_valid_nonzero_table_init_pair(env) {
Some((elem_idx, table_idx)) => {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_init(elem_idx, table_idx))
out.push(Instruction::elem_drop(elem_idx))
}
None => ()
}
true
}
///|
fn gen_valid_append_array_data_seed_instrs(
out : Array[Instruction],
env : GenValidBodyEnv,
) -> Bool {
if env.data_idxs.is_empty() {
return false
}
match env.gc_type_plan.bulk_data_array_idx {
Some(array_idx) => {
let data_idx = env.data_idxs[0]
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::array_new_data(array_idx, data_idx))
true
}
None => false
}
}
///|
fn gen_valid_append_array_elem_seed_instrs(
out : Array[Instruction],
env : GenValidBodyEnv,
) -> Bool {
match (env.gc_type_plan.bulk_elem_array_idx, env.bulk_elem_seed_idx) {
(Some(array_idx), Some(elem_idx)) => {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::array_new_elem(array_idx, elem_idx))
true
}
_ => false
}
}
///|
fn gen_valid_append_array_data_init_instrs(
out : Array[Instruction],
env : GenValidBodyEnv,
) -> Bool {
if env.data_idxs.is_empty() {
return false
}
match env.gc_type_plan.bulk_data_array_idx {
Some(array_idx) => {
let data_idx = env.data_idxs[0]
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_new_default(array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::array_init_data(array_idx, data_idx))
true
}
None => false
}
}
///|
fn gen_valid_append_array_elem_init_instrs(
out : Array[Instruction],
env : GenValidBodyEnv,
) -> Bool {
match (env.gc_type_plan.bulk_elem_array_idx, env.bulk_elem_seed_idx) {
(Some(array_idx), Some(elem_idx)) => {
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_new_default(array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::array_init_elem(array_idx, elem_idx))
true
}
_ => false
}
}
///|
fn gen_valid_append_nested_void_instrs(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
let child = gen_valid_body_env_child(env, add_void_label=true)
let stmt_count = gen_valid_body_stmt_count(ctx, child.depth_left)
for _ in 0.. GenValidTypedStack {
{ values: [], }
}
///|
fn gen_valid_typed_stack_push(
stack : GenValidTypedStack,
vt : ValType,
) -> GenValidTypedStack {
let values = stack.values.copy()
values.push(vt)
{ values, }
}
///|
fn gen_valid_typed_value(
ctx : GenValidContext,
env : GenValidBodyEnv,
vt : ValType,
) -> Array[Instruction] {
if ctx.config.mode == CoverageForced {
return [gen_const_instr(ctx, vt)]
}
let out : Array[Instruction] = []
append_value_instrs(out, ctx, vt, env, prefer_local=true)
out
}
///|
fn gen_valid_typed_pick_local_set_target(
local_types : Array[ValType],
) -> (LocalIdx, ValType)? {
for vt in [ValType::i64(), ValType::f32(), ValType::f64(), ValType::i32()] {
match gen_matching_local_idx(local_types, vt) {
Some(idx) => return Some((idx, vt))
None => ()
}
}
None
}
///|
fn gen_valid_typed_pick_multivalue_block_type(
funcs : Array[GenValidFuncSig],
) -> (TypeIdx, Array[ValType])? {
for func in funcs {
if func.params.is_empty() && func.results.length() > 1 {
return Some((func.type_idx, func.results))
}
}
None
}
///|
fn gen_valid_typed_expr(
ctx : GenValidContext,
env : GenValidBodyEnv,
expected_results : Array[ValType],
fuel : Int32,
) -> Array[Instruction] {
let out : Array[Instruction] = []
let mut stack = gen_valid_typed_stack_empty()
for vt in expected_results {
let value_instrs = if fuel > 0 {
gen_valid_typed_value(ctx, env, vt)
} else {
[gen_const_instr(ctx, vt)]
}
for instr in value_instrs {
out.push(instr)
}
stack = gen_valid_typed_stack_push(stack, vt)
}
ignore(stack)
out
}
///|
fn gen_valid_append_typed_payload_control_blocks(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
vt : ValType,
fuel : Int32,
) -> Unit {
let child = gen_valid_body_env_child(env, add_void_label=true)
let payload_br_body : Array[Instruction] = []
for instr in gen_valid_typed_expr(ctx, child, [vt], fuel - 1) {
payload_br_body.push(instr)
}
payload_br_body.push(Instruction::br(LabelIdx::new(0U)))
payload_br_body.push(Instruction::unreachable_())
out.push(
Instruction::block(BlockType::val_type(vt), Expr::new(payload_br_body)),
)
out.push(Instruction::drop())
let payload_br_if_body : Array[Instruction] = []
for instr in gen_valid_typed_expr(ctx, child, [vt], fuel - 1) {
payload_br_if_body.push(instr)
}
payload_br_if_body.push(
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
)
payload_br_if_body.push(Instruction::br_if(LabelIdx::new(0U)))
out.push(
Instruction::block(BlockType::val_type(vt), Expr::new(payload_br_if_body)),
)
out.push(Instruction::drop())
let payload_br_table_body : Array[Instruction] = []
for instr in gen_valid_typed_expr(ctx, child, [vt], fuel - 1) {
payload_br_table_body.push(instr)
}
payload_br_table_body.push(
Instruction::i32_const(I32(ctx.random_int_from(BodyStream, 3))),
)
payload_br_table_body.push(
Instruction::br_table([LabelIdx::new(0U)], LabelIdx::new(0U)),
)
payload_br_table_body.push(Instruction::unreachable_())
out.push(
Instruction::block(
BlockType::val_type(vt),
Expr::new(payload_br_table_body),
),
)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_nested_payload_branch_block(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
vt : ValType,
fuel : Int32,
) -> Unit {
let child = gen_valid_body_env_child(env, add_void_label=true)
let inner_body : Array[Instruction] = []
for instr in gen_valid_typed_expr(ctx, child, [vt], fuel - 1) {
inner_body.push(instr)
}
let selector = ctx.random_int_from(BodyStream, 3)
if selector == 0 {
inner_body.push(Instruction::br(LabelIdx::new(1U)))
} else if selector == 1 {
inner_body.push(
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
)
inner_body.push(Instruction::br_if(LabelIdx::new(1U)))
inner_body.push(Instruction::br(LabelIdx::new(1U)))
} else {
inner_body.push(
Instruction::i32_const(I32(ctx.random_int_from(BodyStream, 3))),
)
inner_body.push(
Instruction::br_table([LabelIdx::new(1U)], LabelIdx::new(1U)),
)
}
inner_body.push(Instruction::unreachable_())
let outer_body = [
Instruction::block(BlockType::void_(), Expr::new(inner_body)),
Instruction::unreachable_(),
]
out.push(Instruction::block(BlockType::val_type(vt), Expr::new(outer_body)))
out.push(Instruction::drop())
}
///|
fn gen_valid_typed_stmt(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
fuel : Int32,
) -> Unit {
let child = gen_valid_body_env_child(env, add_void_label=true)
match gen_valid_typed_pick_local_set_target(env.local_types) {
Some((idx, vt)) => {
for instr in gen_valid_typed_expr(ctx, env, [vt], fuel) {
out.push(instr)
}
out.push(Instruction::local_set(idx))
}
None => ()
}
if ctx.config.features.allow_v128 {
match gen_matching_local_idx(env.local_types, ValType::v128()) {
Some(idx) => {
for instr in gen_valid_typed_expr(ctx, env, [ValType::v128()], fuel) {
out.push(instr)
}
out.push(Instruction::local_set(idx))
}
None => ()
}
}
match gen_matching_local_idx(env.local_types, ValType::i32()) {
Some(idx) => {
for instr in gen_valid_typed_expr(ctx, env, [ValType::i32()], fuel) {
out.push(instr)
}
out.push(Instruction::local_tee(idx))
out.push(Instruction::drop())
}
None => ()
}
match gen_matching_high_local_idx(env.local_types, ValType::i32(), 16) {
Some(idx) => {
out.push(Instruction::i32_const(I32(1054)))
out.push(Instruction::local_set(idx))
out.push(Instruction::local_get(idx))
out.push(Instruction::drop())
match
gen_matching_high_local_idx_except(
env.local_types,
ValType::i32(),
16,
idx,
) {
Some(write_only_idx) => {
out.push(Instruction::i32_const(I32(1055)))
out.push(Instruction::local_set(write_only_idx))
}
None => ()
}
}
None => ()
}
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new(gen_valid_typed_expr(ctx, child, [ValType::i32()], fuel - 1)),
),
)
out.push(Instruction::drop())
out.push(
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
)
out.push(
Instruction::if_(
BlockType::val_type(ValType::i32()),
gen_valid_typed_expr(ctx, child, [ValType::i32()], fuel - 1),
Some(gen_valid_typed_expr(ctx, child, [ValType::i32()], fuel - 1)),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
Instruction::br_if(LabelIdx::new(0U)),
]),
),
)
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(ctx.random_int_from(BodyStream, 1000))),
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
Instruction::br_if(LabelIdx::new(0U)),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(ctx.random_int_from(BodyStream, 1000))),
Instruction::i32_const(I32(ctx.random_int_from(BodyStream, 3))),
Instruction::br_table([LabelIdx::new(0U)], LabelIdx::new(0U)),
Instruction::unreachable_(),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::loop_(
BlockType::val_type(ValType::i32()),
Expr::new(gen_valid_typed_expr(ctx, child, [ValType::i32()], fuel - 1)),
),
)
out.push(Instruction::drop())
match gen_valid_typed_pick_multivalue_block_type(env.funcs) {
Some((type_idx, results)) => {
let multivalue_body : Array[Instruction] = []
for vt in results {
multivalue_body.push(gen_const_instr(ctx, vt))
}
out.push(
Instruction::block(
BlockType::type_idx(type_idx),
Expr::new(multivalue_body),
),
)
for _ in results {
out.push(Instruction::drop())
}
}
None => ()
}
for
vt in [
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
ValType::v128(),
ValType::funcref(),
] {
gen_valid_append_typed_payload_control_blocks(out, ctx, env, vt, fuel)
gen_valid_append_nested_payload_branch_block(out, ctx, env, vt, fuel)
}
if !env.return_types.is_empty() {
let return_block_body : Array[Instruction] = []
for vt in env.return_types {
for instr in gen_valid_typed_expr(ctx, env, [vt], fuel - 1) {
return_block_body.push(instr)
}
}
return_block_body.push(Instruction::return_())
return_block_body.push(Instruction::unreachable_())
out.push(
Instruction::block(BlockType::void_(), Expr::new(return_block_body)),
)
}
}
///|
fn gen_valid_append_typed_body_generator_slice(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !ctx.config.features.allow_typed_body_generator {
return
}
gen_valid_typed_stmt(out, ctx, env, env.depth_left)
}
///|
fn gen_valid_append_remove_unused_brs_br_if_case(
out : Array[Instruction],
ctx : GenValidContext,
vt : ValType,
) -> Unit {
let body = [
gen_const_instr(ctx, vt),
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
Instruction::br_if(LabelIdx::new(0U)),
]
out.push(Instruction::block(BlockType::val_type(vt), Expr::new(body)))
out.push(Instruction::drop())
}
///|
fn gen_valid_append_remove_unused_brs_br_table_case(
out : Array[Instruction],
ctx : GenValidContext,
vt : ValType,
) -> Unit {
let body = [
gen_const_instr(ctx, vt),
Instruction::i32_const(I32(ctx.random_int_from(BodyStream, 4))),
Instruction::br_table([LabelIdx::new(0U)], LabelIdx::new(0U)),
Instruction::unreachable_(),
]
out.push(Instruction::block(BlockType::val_type(vt), Expr::new(body)))
out.push(Instruction::drop())
}
///|
fn append_value_instrs(
out : Array[Instruction],
ctx : GenValidContext,
vt : ValType,
env : GenValidBodyEnv,
prefer_local~ : Bool = true,
) -> Unit {
if prefer_local && ctx.random_bool_from(BodyStream) {
match gen_matching_local_idx(env.local_types, vt) {
Some(idx) => {
out.push(Instruction::local_get(idx))
return
}
None => ()
}
}
match gen_matching_global_idx(env.globals, vt) {
Some(idx) if ctx.random_int_from(BodyStream, 5) == 0 => {
out.push(Instruction::global_get(idx))
return
}
_ => ()
}
if env.depth_left > 0 &&
!(ctx.config.mode == Natural &&
!env.gc_type_plan.concrete_ref_types.is_empty()) {
if ctx.config.features.allow_calls {
match gen_valid_pick_callable_with_result(ctx, env.funcs, vt) {
Some(target) if ctx.random_int_from(BodyStream, 4) == 0 => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::call(target.idx))
return
}
_ => ()
}
}
if !env.mems.is_empty() &&
vt == ValType::i32() &&
ctx.random_int_from(BodyStream, 5) == 0 {
out.push(Instruction::memory_size(MemIdx::new(0U)))
return
}
if ctx.config.features.allow_call_indirect && !env.tables.is_empty() {
match gen_valid_pick_callable_with_result(ctx, env.funcs, vt) {
Some(target) if ctx.random_int_from(BodyStream, 4) == 0 => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(0)))
out.push(
Instruction::call_indirect(target.type_idx, TableIdx::new(0U)),
)
return
}
_ => ()
}
}
if ctx.config.features.allow_branch_heavy_control &&
ctx.random_int_from(BodyStream, 5) == 0 {
let then_body : Array[Instruction] = []
let else_body : Array[Instruction] = []
let child = gen_valid_body_env_child(env)
append_value_instrs(then_body, ctx, vt, child, prefer_local=false)
append_value_instrs(else_body, ctx, vt, child, prefer_local=false)
out.push(
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
)
out.push(
Instruction::if_(BlockType::val_type(vt), then_body, Some(else_body)),
)
return
}
if ctx.config.features.allow_branch_heavy_control &&
ctx.random_int_from(BodyStream, 5) == 0 {
let child_body : Array[Instruction] = []
append_value_instrs(
child_body,
ctx,
vt,
gen_valid_body_env_child(env),
prefer_local=false,
)
out.push(
Instruction::block(BlockType::val_type(vt), Expr::new(child_body)),
)
return
}
if !env.tables.is_empty() {
let TableType(rt, _) = env.tables[0]
if vt == ValType::ref_type(rt) && ctx.random_int_from(BodyStream, 4) == 0 {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_get(TableIdx::new(0U)))
return
}
}
if !env.mems.is_empty() {
let memarg = gen_valid_memarg()
match vt {
NumTypeValType(I32NumType) if ctx.random_int_from(BodyStream, 4) == 0 => {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_load(memarg))
return
}
NumTypeValType(I64NumType) if ctx.random_int_from(BodyStream, 4) == 0 => {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i64_load(memarg))
return
}
NumTypeValType(F32NumType) if ctx.random_int_from(BodyStream, 4) == 0 => {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::f32_load(memarg))
return
}
NumTypeValType(F64NumType) if ctx.random_int_from(BodyStream, 4) == 0 => {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::f64_load(memarg))
return
}
_ => ()
}
}
if !env.tables.is_empty() &&
vt == ValType::i32() &&
ctx.random_int_from(BodyStream, 4) == 0 {
out.push(Instruction::table_size(TableIdx::new(0U)))
return
}
}
match vt {
RefTypeValType(rt) => {
let heap_type = rt.get_heap_type()
if ValType::ref_type(rt) == ValType::funcref() {
match env.declared_ref_func_idx {
Some(func_idx) if ctx.random_bool_from(BodyStream) => {
out.push(Instruction::ref_func(func_idx))
return
}
_ => ()
}
}
if vt == ValType::stringref() {
match
(
env.gc_type_plan.string_wtf16_array_idx,
env.gc_type_plan.string_utf8_array_idx,
) {
(Some(string_wtf16_array_idx), _) if ctx.random_int_from(
BodyStream,
3,
) ==
0 => {
out.push(Instruction::i32_const(I32(4)))
out.push(Instruction::array_new_default(string_wtf16_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::string_new_wtf16_array())
return
}
(_, Some(string_utf8_array_idx)) if ctx.random_int_from(BodyStream, 3) ==
0 => {
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::array_new_default(string_utf8_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(4)))
out.push(
if ctx.random_bool_from(BodyStream) {
Instruction::string_new_lossy_utf8_array()
} else {
Instruction::string_new_wtf8_array()
},
)
return
}
_ => ()
}
}
if vt == ValType::ref_null_exn() &&
!env.tags.is_empty() &&
ctx.random_int_from(BodyStream, 3) == 0 {
let tag_idx = TagIdx::new(0U)
out.push(
Instruction::try_table(
BlockType::val_type(vt),
[
if ctx.random_bool_from(BodyStream) {
Catch::ref_(tag_idx, LabelIdx::new(0U))
} else {
Catch::all_ref(LabelIdx::new(0U))
},
],
Expr::new([Instruction::throw_(tag_idx)]),
),
)
return
}
match heap_type {
HeapType(type_idx) => {
match
(
env.gc_type_plan.descriptor_struct_idx,
env.gc_type_plan.descriptor_type_idx,
) {
(Some(described_idx), Some(descriptor_idx)) if type_idx ==
described_idx &&
ctx.random_int_from(BodyStream, 3) == 0 => {
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
return
}
(Some(_described_idx), Some(descriptor_idx)) if type_idx ==
descriptor_idx &&
ctx.random_int_from(BodyStream, 3) == 0 => {
out.push(Instruction::struct_new_default(descriptor_idx))
return
}
_ => ()
}
if gen_valid_contains_type_idx(
env.gc_type_plan.struct_type_idxs,
type_idx,
) &&
ctx.random_int_from(BodyStream, 3) == 0 {
out.push(Instruction::struct_new_default(type_idx))
return
}
match env.gc_type_plan.bulk_data_array_idx {
Some(array_idx) if type_idx == array_idx &&
ctx.random_int_from(BodyStream, 4) == 0 &&
gen_valid_append_array_data_seed_instrs(out, env) => return
_ => ()
}
match env.gc_type_plan.bulk_elem_array_idx {
Some(array_idx) if type_idx == array_idx &&
ctx.random_int_from(BodyStream, 4) == 0 &&
gen_valid_append_array_elem_seed_instrs(out, env) => return
_ => ()
}
if gen_valid_contains_type_idx(
env.gc_type_plan.array_type_idxs,
type_idx,
) &&
ctx.random_int_from(BodyStream, 3) == 0 {
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_new_default(type_idx))
return
}
}
_ => ()
}
if env.depth_left > 0 {
if !rt.is_nullable() && ctx.random_int_from(BodyStream, 4) == 0 {
out.push(
Instruction::block(
BlockType::val_type(ValType::ref_type(rt)),
Expr::new([
Instruction::ref_null(heap_type),
Instruction::br_on_non_null(LabelIdx::new(0U)),
Instruction::ref_as_non_null(),
]),
),
)
return
}
if rt == RefType::abs(AbsHeapType::any()) &&
ctx.random_int_from(BodyStream, 5) == 0 {
out.push(
Instruction::block(
BlockType::val_type(ValType::ref_type(rt)),
Expr::new([
Instruction::ref_null(heap_type),
Instruction::br_on_cast(
LabelIdx::new(0U),
true,
HeapType::abs(AbsHeapType::any()),
true,
HeapType::abs(AbsHeapType::i31()),
),
]),
),
)
return
}
if rt == RefType::abs(AbsHeapType::any()) &&
ctx.random_int_from(BodyStream, 5) == 0 {
out.push(
Instruction::block(
BlockType::val_type(ValType::ref_type(rt)),
Expr::new([
Instruction::ref_null(heap_type),
Instruction::br_on_cast_fail(
LabelIdx::new(0U),
true,
HeapType::abs(AbsHeapType::any()),
true,
HeapType::abs(AbsHeapType::i31()),
),
]),
),
)
return
}
}
out.push(
if rt.is_exact() {
Instruction::ref_null_type(rt)
} else {
Instruction::ref_null(heap_type)
},
)
}
_ => out.push(gen_const_instr(ctx, vt))
}
}
///|
fn gen_valid_append_natural_exact_descriptor_stmt(
out : Array[Instruction],
env : GenValidBodyEnv,
) -> Bool {
match
(
env.gc_type_plan.descriptor_struct_idx,
env.gc_type_plan.descriptor_type_idx,
) {
(Some(described_idx), Some(_descriptor_idx)) => {
let exact_described = RefType::new(
true,
HeapType::new(described_idx),
exact=true,
)
out.push(Instruction::ref_null_type(exact_described))
out.push(Instruction::ref_get_desc(described_idx))
out.push(Instruction::drop())
out.push(Instruction::ref_null_type(exact_described))
out.push(Instruction::ref_test_desc(true, HeapType::new(described_idx)))
out.push(Instruction::drop())
out.push(Instruction::ref_null_type(exact_described))
out.push(
Instruction::ref_cast_desc_eq(true, HeapType::new(described_idx)),
)
out.push(Instruction::drop())
true
}
_ => false
}
}
///|
fn gen_valid_append_natural_bulk_array_stmt(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Bool {
match ctx.random_int_from(BodyStream, 4) {
0 =>
if gen_valid_append_array_data_seed_instrs(out, env) {
out.push(Instruction::drop())
true
} else if gen_valid_append_array_data_init_instrs(out, env) {
true
} else if gen_valid_append_array_elem_seed_instrs(out, env) {
out.push(Instruction::drop())
true
} else if gen_valid_append_array_elem_init_instrs(out, env) {
true
} else {
false
}
1 =>
if gen_valid_append_array_elem_seed_instrs(out, env) {
out.push(Instruction::drop())
true
} else if gen_valid_append_array_elem_init_instrs(out, env) {
true
} else if gen_valid_append_array_data_seed_instrs(out, env) {
out.push(Instruction::drop())
true
} else if gen_valid_append_array_data_init_instrs(out, env) {
true
} else {
false
}
2 =>
if gen_valid_append_array_data_init_instrs(out, env) {
true
} else if gen_valid_append_array_data_seed_instrs(out, env) {
out.push(Instruction::drop())
true
} else if gen_valid_append_array_elem_init_instrs(out, env) {
true
} else if gen_valid_append_array_elem_seed_instrs(out, env) {
out.push(Instruction::drop())
true
} else {
false
}
_ =>
if gen_valid_append_array_elem_init_instrs(out, env) {
true
} else if gen_valid_append_array_elem_seed_instrs(out, env) {
out.push(Instruction::drop())
true
} else if gen_valid_append_array_data_init_instrs(out, env) {
true
} else if gen_valid_append_array_data_seed_instrs(out, env) {
out.push(Instruction::drop())
true
} else {
false
}
}
}
///|
fn gen_valid_append_natural_mixed_catch_stmt(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Bool {
if env.tags.is_empty() {
return false
}
let tag_idx = TagIdx::new(0U)
if ctx.random_bool_from(BodyStream) {
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[
Catch::new(tag_idx, LabelIdx::new(0U)),
Catch::all(LabelIdx::new(0U)),
],
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::throw_(tag_idx)],
Some([
Instruction::ref_null(HeapType::abs(AbsHeapType::exn())),
Instruction::throw_ref(),
]),
),
]),
),
]),
),
)
return true
}
let exnref = ValType::ref_type(
RefType::new(false, HeapType::abs(AbsHeapType::exn())),
)
out.push(
Instruction::block(
BlockType::val_type(exnref),
Expr::new([
Instruction::try_table(
BlockType::val_type(exnref),
[
Catch::ref_(tag_idx, LabelIdx::new(0U)),
Catch::all_ref(LabelIdx::new(0U)),
],
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
Instruction::br_if(LabelIdx::new(0U)),
]),
),
Instruction::throw_(tag_idx),
]),
),
]),
),
)
out.push(Instruction::drop())
true
}
///|
fn gen_valid_append_natural_gc_stmt(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Bool {
if ctx.config.mode != Natural || !ctx.config.features.allow_ref_types {
return false
}
match ctx.random_int_from(BodyStream, 10) {
0 =>
match
(
env.gc_type_plan.descriptor_struct_idx,
env.gc_type_plan.descriptor_type_idx,
) {
(Some(described_idx), Some(descriptor_idx)) => {
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
out.push(Instruction::ref_get_desc(described_idx))
out.push(Instruction::drop())
true
}
_ => false
}
1 => gen_valid_append_natural_exact_descriptor_stmt(out, env)
2 =>
match
(
env.gc_type_plan.descriptor_struct_idx,
env.gc_type_plan.descriptor_type_idx,
) {
(Some(described_idx), Some(descriptor_idx)) => {
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
out.push(
Instruction::ref_test_desc(true, HeapType::new(described_idx)),
)
out.push(Instruction::drop())
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
out.push(
Instruction::ref_cast_desc_eq(true, HeapType::new(described_idx)),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(
ValType::ref_type(
RefType::new(false, HeapType::new(descriptor_idx)),
),
),
Expr::new([
Instruction::ref_null(HeapType::new(descriptor_idx)),
Instruction::br_on_non_null(LabelIdx::new(0U)),
Instruction::unreachable_(),
]),
),
)
out.push(Instruction::drop())
true
}
_ => false
}
3 =>
match env.gc_type_plan.string_wtf16_array_idx {
Some(string_wtf16_array_idx) => {
out.push(Instruction::i32_const(I32(4)))
out.push(Instruction::array_new_default(string_wtf16_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::string_new_wtf16_array())
out.push(Instruction::drop())
true
}
None => false
}
4 =>
match env.gc_type_plan.string_utf8_array_idx {
Some(string_utf8_array_idx) => {
out.push(Instruction::string_const(b"gen-valid-string"))
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::array_new_default(string_utf8_array_idx))
out.push(Instruction::i32_const(I32(0)))
if ctx.random_bool_from(BodyStream) {
out.push(Instruction::string_encode_utf8_array())
} else if ctx.random_bool_from(BodyStream) {
out.push(Instruction::string_encode_lossy_utf8_array())
} else {
out.push(Instruction::string_encode_wtf8_array())
}
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::array_new_default(string_utf8_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(4)))
if ctx.random_bool_from(BodyStream) {
out.push(Instruction::string_new_lossy_utf8_array())
} else {
out.push(Instruction::string_new_wtf8_array())
}
out.push(Instruction::drop())
true
}
None => false
}
5 => gen_valid_append_natural_bulk_array_stmt(out, ctx, env)
6 => {
out.push(
Instruction::block(
BlockType::val_type(
ValType::ref_type(RefType::abs(AbsHeapType::any())),
),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::any())),
Instruction::br_on_cast(
LabelIdx::new(0U),
true,
HeapType::abs(AbsHeapType::any()),
true,
HeapType::abs(AbsHeapType::i31()),
),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(
ValType::ref_type(RefType::abs(AbsHeapType::any())),
),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::any())),
Instruction::br_on_cast_fail(
LabelIdx::new(0U),
true,
HeapType::abs(AbsHeapType::any()),
true,
HeapType::abs(AbsHeapType::i31()),
),
]),
),
)
out.push(Instruction::drop())
true
}
7 =>
if !env.tags.is_empty() {
let tag_idx = TagIdx::new(0U)
let exnref = ValType::ref_type(
RefType::new(false, HeapType::abs(AbsHeapType::exn())),
)
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::new(tag_idx, LabelIdx::new(0U))],
Expr::new([Instruction::throw_(tag_idx)]),
),
]),
),
)
out.push(
Instruction::block(
BlockType::val_type(exnref),
Expr::new([
Instruction::try_table(
BlockType::val_type(exnref),
[Catch::ref_(tag_idx, LabelIdx::new(0U))],
Expr::new([Instruction::throw_(tag_idx)]),
),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(exnref),
Expr::new([
Instruction::try_table(
BlockType::val_type(exnref),
[Catch::all_ref(LabelIdx::new(0U))],
Expr::new([Instruction::throw_(tag_idx)]),
),
]),
),
)
out.push(Instruction::drop())
true
} else {
false
}
8 => gen_valid_append_natural_mixed_catch_stmt(out, ctx, env)
_ => {
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::exn())),
Instruction::throw_ref(),
]),
),
]),
),
)
true
}
}
}
///|
fn append_void_stmt(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
let branchy = ctx.config.features.allow_branch_heavy_control
match ctx.random_int_from(BodyStream, if branchy { 14 } else { 10 }) {
0 => out.push(Instruction::nop())
1 => {
let vt = gen_valid_valtype(ctx)
append_value_instrs(out, ctx, vt, env, prefer_local=false)
out.push(Instruction::drop())
}
2 =>
if env.local_types.is_empty() {
out.push(Instruction::nop())
} else {
let idx = ctx.random_int_from(BodyStream, env.local_types.length())
let vt = env.local_types[idx]
if ctx.config.mode == CoverageForced {
out.push(gen_const_instr(ctx, vt))
} else {
append_value_instrs(
out,
ctx,
vt,
gen_valid_body_env_child(env),
prefer_local=false,
)
}
out.push(
Instruction::local_set(LocalIdx::new(idx.reinterpret_as_uint())),
)
}
3 =>
match
gen_matching_global_idx(
env.globals,
gen_valid_valtype(ctx),
mutable_only=true,
) {
Some(idx) => {
let GlobalIdx(idx_u) = idx
let GlobalType(vt, _) = env.globals[idx_u.reinterpret_as_int()]
if ctx.config.mode == CoverageForced {
out.push(gen_const_instr(ctx, vt))
} else {
append_value_instrs(
out,
ctx,
vt,
gen_valid_body_env_child(env),
prefer_local=false,
)
}
out.push(Instruction::global_set(idx))
}
None => out.push(Instruction::nop())
}
4 =>
if ctx.config.features.allow_calls {
match gen_valid_pick_callable(ctx, env.funcs) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::call(target.idx))
gen_valid_append_call_result_drops(out, target.results)
}
None => out.push(Instruction::nop())
}
} else {
out.push(Instruction::nop())
}
5 =>
if ctx.config.features.allow_call_indirect && !env.tables.is_empty() {
match gen_valid_pick_callable(ctx, env.funcs) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(0)))
out.push(
Instruction::call_indirect(target.type_idx, TableIdx::new(0U)),
)
gen_valid_append_call_result_drops(out, target.results)
}
None => out.push(Instruction::nop())
}
} else {
out.push(Instruction::nop())
}
6 =>
if !env.mems.is_empty() {
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::drop())
gen_valid_append_scalar_memory_ops(out)
} else {
out.push(Instruction::nop())
}
7 =>
if !env.tables.is_empty() {
let TableType(rt, _) = env.tables[0]
out.push(Instruction::table_size(TableIdx::new(0U)))
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(0)))
gen_valid_append_table_ref_value(out, ctx, env, rt)
out.push(Instruction::table_set(TableIdx::new(0U)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_get(TableIdx::new(0U)))
out.push(Instruction::drop())
} else {
out.push(Instruction::nop())
}
8 =>
if !gen_valid_append_memory_bulk_ops(out, ctx, env) {
out.push(Instruction::nop())
}
9 =>
if !gen_valid_append_table_bulk_ops(out, ctx, env) {
out.push(Instruction::nop())
}
10 => {
let body : Array[Instruction] = []
gen_valid_append_nested_void_instrs(body, ctx, env)
out.push(Instruction::block(BlockType::void_(), Expr::new(body)))
}
11 => {
let body : Array[Instruction] = []
gen_valid_append_nested_void_instrs(body, ctx, env)
if branchy {
body.push(
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
)
body.push(Instruction::br_if(LabelIdx::new(0U)))
}
out.push(Instruction::loop_(BlockType::void_(), Expr::new(body)))
}
12 => {
let then_body : Array[Instruction] = []
let else_body : Array[Instruction] = []
let child = gen_valid_body_env_child(env)
let branch_stmt_count = gen_valid_body_stmt_count(ctx, child.depth_left)
for _ in 0..
if branchy && env.label_depth > 0 {
if ctx.random_bool_from(BodyStream) {
out.push(
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
)
out.push(Instruction::br_if(LabelIdx::new(0U)))
} else {
out.push(Instruction::br(LabelIdx::new(0U)))
}
} else {
out.push(Instruction::nop())
}
}
}
///|
fn gen_valid_append_gc_prelude(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !ctx.config.features.allow_ref_types {
return
}
if !env.gc_type_plan.struct_type_idxs.is_empty() {
let struct_idx = env.gc_type_plan.struct_type_idxs[0]
out.push(Instruction::i32_const(I32(42)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::struct_get(struct_idx, U32::new(0U)))
out.push(Instruction::drop())
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::any())))
out.push(Instruction::ref_test(true, HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::drop())
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::any())))
out.push(Instruction::ref_cast(true, HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::drop())
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::any())))
out.push(Instruction::ref_as_non_null())
out.push(Instruction::drop())
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::ref_eq())
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::ref_null(HeapType::new(struct_idx)),
Instruction::br_on_null(LabelIdx::new(0U)),
Instruction::drop(),
]),
),
)
}
match env.gc_type_plan.packed_struct_idx {
Some(packed_struct_idx) => {
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::struct_new(packed_struct_idx))
out.push(Instruction::struct_get_s(packed_struct_idx, U32::new(0U)))
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(3)))
out.push(Instruction::i32_const(I32(4)))
out.push(Instruction::struct_new(packed_struct_idx))
out.push(Instruction::struct_get_u(packed_struct_idx, U32::new(1U)))
out.push(Instruction::drop())
}
None => ()
}
match
(
env.gc_type_plan.descriptor_struct_idx,
env.gc_type_plan.descriptor_type_idx,
) {
(Some(described_idx), Some(descriptor_idx)) => {
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
out.push(Instruction::ref_get_desc(described_idx))
out.push(Instruction::drop())
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
out.push(Instruction::ref_test_desc(true, HeapType::new(described_idx)))
out.push(Instruction::drop())
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
out.push(
Instruction::ref_cast_desc_eq(true, HeapType::new(described_idx)),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(
ValType::ref_type(
RefType::new(false, HeapType::new(descriptor_idx)),
),
),
Expr::new([
Instruction::ref_null(HeapType::new(descriptor_idx)),
Instruction::br_on_non_null(LabelIdx::new(0U)),
Instruction::unreachable_(),
]),
),
)
out.push(Instruction::drop())
}
_ => ()
}
if !env.gc_type_plan.array_type_idxs.is_empty() {
let array_idx = env.gc_type_plan.array_type_idxs[0]
out.push(Instruction::i32_const(I32(9)))
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::array_new(array_idx))
out.push(Instruction::array_len())
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(5)))
out.push(Instruction::i32_const(I32(6)))
out.push(Instruction::array_new_fixed(array_idx, U32::new(2U)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::array_get(array_idx))
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::array_new_default(array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(7)))
out.push(Instruction::array_set(array_idx))
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::array_new_default(array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(8)))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_fill(array_idx))
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::array_new_default(array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::array_new_default(array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_copy(array_idx, array_idx))
}
match env.gc_type_plan.packed_i8_array_idx {
Some(packed_i8_array_idx) => {
out.push(Instruction::i32_const(I32(11)))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_new(packed_i8_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::array_get_s(packed_i8_array_idx))
out.push(Instruction::drop())
}
None => ()
}
match env.gc_type_plan.packed_i16_array_idx {
Some(packed_i16_array_idx) => {
out.push(Instruction::i32_const(I32(12)))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_new(packed_i16_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::array_get_u(packed_i16_array_idx))
out.push(Instruction::drop())
}
None => ()
}
match env.gc_type_plan.string_wtf16_array_idx {
Some(string_wtf16_array_idx) => {
out.push(Instruction::i32_const(I32(4)))
out.push(Instruction::array_new_default(string_wtf16_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::string_new_wtf16_array())
out.push(Instruction::drop())
}
None => ()
}
match env.gc_type_plan.string_utf8_array_idx {
Some(string_utf8_array_idx) => {
out.push(Instruction::string_const(b"gen-valid-string"))
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::array_new_default(string_utf8_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::string_encode_utf8_array())
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::array_new_default(string_utf8_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(4)))
out.push(Instruction::string_new_lossy_utf8_array())
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::array_new_default(string_utf8_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(4)))
out.push(Instruction::string_new_wtf8_array())
out.push(Instruction::drop())
out.push(Instruction::string_const(b"gen-valid-string"))
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::array_new_default(string_utf8_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::string_encode_lossy_utf8_array())
out.push(Instruction::drop())
out.push(Instruction::string_const(b"gen-valid-string"))
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::array_new_default(string_utf8_array_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::string_encode_wtf8_array())
out.push(Instruction::drop())
}
None => ()
}
out.push(
Instruction::block(
BlockType::val_type(ValType::ref_type(RefType::abs(AbsHeapType::any()))),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::any())),
Instruction::br_on_cast(
LabelIdx::new(0U),
true,
HeapType::abs(AbsHeapType::any()),
true,
HeapType::abs(AbsHeapType::i31()),
),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(ValType::ref_type(RefType::abs(AbsHeapType::any()))),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::any())),
Instruction::br_on_cast_fail(
LabelIdx::new(0U),
true,
HeapType::abs(AbsHeapType::any()),
true,
HeapType::abs(AbsHeapType::i31()),
),
]),
),
)
out.push(Instruction::drop())
if !env.tags.is_empty() {
let tag_idx = TagIdx::new(0U)
let exnref = ValType::ref_type(
RefType::new(false, HeapType::abs(AbsHeapType::exn())),
)
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::new(tag_idx, LabelIdx::new(0U))],
Expr::new([Instruction::throw_(tag_idx)]),
),
]),
),
)
out.push(
Instruction::block(
BlockType::val_type(exnref),
Expr::new([
Instruction::try_table(
BlockType::val_type(exnref),
[Catch::ref_(tag_idx, LabelIdx::new(0U))],
Expr::new([Instruction::throw_(tag_idx)]),
),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(exnref),
Expr::new([
Instruction::try_table(
BlockType::val_type(exnref),
[Catch::all_ref(LabelIdx::new(0U))],
Expr::new([Instruction::throw_(tag_idx)]),
),
]),
),
)
out.push(Instruction::drop())
}
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::exn())),
Instruction::throw_ref(),
]),
),
]),
),
)
match env.declared_ref_func_idx {
Some(func_idx) =>
match gen_valid_callable_by_idx(env.funcs, func_idx) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::ref_func(func_idx))
out.push(Instruction::call_ref(target.type_idx))
gen_valid_append_call_result_drops(out, target.results)
}
None => ()
}
None => ()
}
}
///|
fn gen_valid_append_scalar_numeric_drop(
out : Array[Instruction],
instrs : Array[Instruction],
) -> Unit {
for instr in instrs {
out.push(instr)
}
out.push(Instruction::drop())
}
///|
fn gen_valid_append_numeric_boundary_constants(
out : Array[Instruction],
ctx : GenValidContext,
) -> Unit {
let i32_boundary_constants = [0, 1, -1, -2147483647 - 1, 2147483647, 1024]
for value in i32_boundary_constants {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i32_const(I32(value)),
])
}
let i64_boundary_constants = [
0L,
1L,
-1L,
-9223372036854775807L - 1L,
9223372036854775807L,
1099511627776L,
]
for value in i64_boundary_constants {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i64_const(I64(value)),
])
}
let f32_boundary_constants = [0x80000000U, 0x7f800000U, 0xff800000U]
for bits in f32_boundary_constants {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f32_const(F32(Float::reinterpret_from_uint(bits))),
])
}
let f64_boundary_constants = [
0x8000000000000000UL, 0x7ff0000000000000UL, 0xfff0000000000000UL,
]
for bits in f64_boundary_constants {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f64_const(F64(bits.reinterpret_as_double())),
])
}
// NaN payloads intentionally stay out of the Binaryen-oracle compatibility
// wrapper profile because MoonBit float equality treats NaNs as unequal,
// which would make two byte-identical generated modules fail structural Eq.
if ctx.config != GenValidConfig::binaryen_oracle_coverage_forced_default() {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f32_const(F32(Float::reinterpret_from_uint(0x7fc00001U))),
])
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f64_const(F64(0x7ff8000000000001UL.reinterpret_as_double())),
])
}
}
///|
fn gen_valid_append_typed_select(
out : Array[Instruction],
ctx : GenValidContext,
vt : ValType,
) -> Unit {
out.push(gen_const_instr(ctx, vt))
out.push(gen_const_instr(ctx, vt))
out.push(
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
)
out.push(Instruction::select(types=Some([vt])))
out.push(Instruction::drop())
}
///|
fn gen_valid_append_core_control_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !ctx.config.features.allow_branch_heavy_control {
return
}
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::br_table([LabelIdx::new(0U)], LabelIdx::new(0U)),
]),
),
)
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::unreachable_()]),
),
)
match gen_matching_local_idx(env.local_types, ValType::i32()) {
Some(idx) => {
out.push(Instruction::i32_const(I32(7)))
out.push(Instruction::local_tee(idx))
out.push(Instruction::drop())
}
None => ()
}
for
vt in [
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
ValType::v128(),
ValType::funcref(),
] {
gen_valid_append_typed_select(out, ctx, vt)
}
}
///|
fn gen_valid_append_call_ref_source_variants(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !ctx.config.features.allow_ref_types {
return
}
match env.declared_ref_func_idx {
Some(func_idx) =>
match gen_valid_callable_by_idx(env.funcs, func_idx) {
Some(target) => {
let fref = ValType::ref_type(
RefType::new(true, HeapType::new(target.type_idx)),
)
match gen_matching_local_idx(env.local_types, fref) {
Some(local_idx) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::ref_func(target.idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::call_ref(target.type_idx))
gen_valid_append_call_result_drops(out, target.results)
}
None => ()
}
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(
Instruction::block(
BlockType::val_type(fref),
Expr::new([Instruction::ref_func(target.idx)]),
),
)
out.push(Instruction::call_ref(target.type_idx))
gen_valid_append_call_result_drops(out, target.results)
match gen_matching_global_idx(env.globals, fref) {
Some(global_idx) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::global_get(global_idx))
out.push(Instruction::call_ref(target.type_idx))
gen_valid_append_call_result_drops(out, target.results)
}
None => ()
}
}
None => ()
}
None => ()
}
for i = 0; i < env.tables.length(); i = i + 1 {
let TableType(rt, _) = env.tables[i]
match gen_valid_func_type_idx_from_ref_type(rt) {
Some(type_idx) =>
for target in env.funcs {
if target.type_idx == type_idx {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(0)))
out.push(
Instruction::table_get(TableIdx::new(i.reinterpret_as_uint())),
)
out.push(Instruction::call_ref(target.type_idx))
gen_valid_append_call_result_drops(out, target.results)
return
}
}
None => ()
}
}
match gen_valid_first_nonzero_funcref_table_idx(env.tables) {
Some(table_idx) =>
match gen_valid_pick_callable(ctx, env.funcs) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::table_get(table_idx))
out.push(Instruction::ref_cast(false, HeapType::new(target.type_idx)))
out.push(Instruction::call_ref(target.type_idx))
gen_valid_append_call_result_drops(out, target.results)
}
None => ()
}
None => ()
}
}
///|
fn gen_valid_append_direct_call_graph_variants(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !ctx.config.features.allow_calls {
return
}
match env.declared_ref_func_idx {
Some(first_defined_idx) => {
let first_defined_i = gen_valid_func_idx_to_int(first_defined_idx)
for target in env.funcs {
if gen_valid_func_idx_to_int(target.idx) < first_defined_i {
gen_valid_append_direct_call(out, ctx, env, target)
break
}
}
}
None => ()
}
match env.current_func_idx {
Some(current_idx) => {
match gen_valid_callable_by_idx(env.funcs, current_idx) {
Some(target) => gen_valid_append_direct_call(out, ctx, env, target)
None => ()
}
match env.declared_ref_func_idx {
Some(first_defined_idx) => {
let current_i = gen_valid_func_idx_to_int(current_idx)
let first_defined_i = gen_valid_func_idx_to_int(first_defined_idx)
if current_i == first_defined_i {
let next_idx = FuncIdx::new((current_i + 1).reinterpret_as_uint())
match gen_valid_callable_by_idx(env.funcs, next_idx) {
Some(target) =>
gen_valid_append_direct_call(out, ctx, env, target)
None => ()
}
} else if current_i == first_defined_i + 1 {
match gen_valid_callable_by_idx(env.funcs, first_defined_idx) {
Some(target) =>
gen_valid_append_direct_call(out, ctx, env, target)
None => ()
}
}
}
None => ()
}
}
None => ()
}
}
///|
fn gen_valid_funcref_table_indices(
tables : Array[TableType],
) -> Array[TableIdx] {
let result : Array[TableIdx] = []
for i = 0; i < tables.length(); i = i + 1 {
let TableType(rt, _) = tables[i]
if ValType::ref_type(rt) == ValType::funcref() {
result.push(TableIdx::new(i.reinterpret_as_uint()))
}
}
result
}
///|
fn gen_valid_first_nonzero_funcref_table_idx(
tables : Array[TableType],
) -> TableIdx? {
for i = 1; i < tables.length(); i = i + 1 {
let TableType(rt, _) = tables[i]
if ValType::ref_type(rt) == ValType::funcref() {
return Some(TableIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_valid_append_call_indirect_variants(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !ctx.config.features.allow_call_indirect || env.tables.is_empty() {
return
}
let funcref_tables = gen_valid_funcref_table_indices(env.tables)
if funcref_tables.is_empty() {
return
}
let primary_table = funcref_tables[0]
match gen_valid_pick_callable(ctx, env.funcs) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::call_indirect(target.type_idx, primary_table))
gen_valid_append_call_result_drops(out, target.results)
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::call_indirect(target.type_idx, primary_table))
gen_valid_append_call_result_drops(out, target.results)
match gen_valid_first_nonzero_funcref_table_idx(env.tables) {
Some(nonzero_table) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::call_indirect(target.type_idx, nonzero_table))
gen_valid_append_call_result_drops(out, target.results)
}
None => ()
}
}
None => ()
}
}
///|
fn gen_valid_append_nested_tail_call_variants(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
returns : Array[ValType],
) -> Unit {
if !ctx.config.features.allow_tail_calls || !ctx.config.features.allow_calls {
return
}
match gen_valid_pick_callable_with_results(ctx, env.funcs, returns) {
Some(target) => {
let nested : Array[Instruction] = []
gen_valid_append_call_args(nested, ctx, env, target.params)
nested.push(Instruction::return_call(target.idx))
out.push(Instruction::block(BlockType::void_(), Expr::new(nested)))
let then_tail : Array[Instruction] = []
gen_valid_append_call_args(then_tail, ctx, env, target.params)
then_tail.push(Instruction::return_call(target.idx))
let else_tail : Array[Instruction] = []
gen_valid_append_call_args(else_tail, ctx, env, target.params)
else_tail.push(Instruction::return_call(target.idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::if_(BlockType::void_(), then_tail, Some(else_tail)),
]),
),
)
}
None => ()
}
if ctx.config.features.allow_call_indirect && !env.tables.is_empty() {
let TableType(rt, _) = env.tables[0]
if ValType::ref_type(rt) == ValType::funcref() {
match gen_valid_pick_callable_with_results(ctx, env.funcs, returns) {
Some(target) => {
let nested : Array[Instruction] = []
gen_valid_append_call_args(nested, ctx, env, target.params)
nested.push(Instruction::i32_const(I32(1)))
nested.push(
Instruction::return_call_indirect(
target.type_idx,
TableIdx::new(0U),
),
)
out.push(Instruction::block(BlockType::void_(), Expr::new(nested)))
}
None => ()
}
}
}
if ctx.config.features.allow_ref_types {
match
gen_valid_declared_ref_callable_with_results(
env.funcs,
env.declared_ref_func_idx,
returns,
) {
Some(target) => {
let fref = ValType::ref_type(
RefType::new(true, HeapType::new(target.type_idx)),
)
let nested : Array[Instruction] = []
gen_valid_append_call_args(nested, ctx, env, target.params)
nested.push(
Instruction::block(
BlockType::val_type(fref),
Expr::new([Instruction::ref_func(target.idx)]),
),
)
nested.push(Instruction::return_call_ref(target.type_idx))
out.push(Instruction::block(BlockType::void_(), Expr::new(nested)))
}
None => ()
}
}
}
///|
fn gen_valid_append_tail_call_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
returns : Array[ValType],
) -> Unit {
if !ctx.config.features.allow_tail_calls {
return
}
match gen_valid_pick_callable_with_results(ctx, env.funcs, returns) {
Some(target) if ctx.config.features.allow_calls => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::return_call(target.idx))
}
_ => ()
}
if ctx.config.features.allow_call_indirect && !env.tables.is_empty() {
let TableType(rt, _) = env.tables[0]
if ValType::ref_type(rt) == ValType::funcref() {
match gen_valid_pick_callable_with_results(ctx, env.funcs, returns) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(0)))
out.push(
Instruction::return_call_indirect(
target.type_idx,
TableIdx::new(0U),
),
)
}
_ => ()
}
}
}
if ctx.config.features.allow_ref_types {
match
gen_valid_declared_ref_callable_with_results(
env.funcs,
env.declared_ref_func_idx,
returns,
) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::ref_func(target.idx))
out.push(Instruction::return_call_ref(target.type_idx))
}
None => ()
}
}
}
///|
fn gen_valid_append_expanded_scalar_numeric_ops(
out : Array[Instruction],
ctx : GenValidContext,
) -> Unit {
gen_valid_append_numeric_boundary_constants(out, ctx)
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i32_const(I32(0)),
Instruction::i32_eqz(),
])
let i32_unary_ops = [
Instruction::i32_clz(),
Instruction::i32_ctz(),
Instruction::i32_popcnt(),
]
for op in i32_unary_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i32_const(I32(84)),
op,
])
}
let i32_cmp_ops = [
Instruction::i32_eq(),
Instruction::i32_ne(),
Instruction::i32_lt_s(),
Instruction::i32_lt_u(),
Instruction::i32_gt_s(),
Instruction::i32_gt_u(),
Instruction::i32_le_s(),
Instruction::i32_le_u(),
Instruction::i32_ge_s(),
Instruction::i32_ge_u(),
]
for op in i32_cmp_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i32_const(I32(11)),
Instruction::i32_const(I32(3)),
op,
])
}
let i32_binary_ops = [
Instruction::i32_add(),
Instruction::i32_sub(),
Instruction::i32_mul(),
Instruction::i32_div_s(),
Instruction::i32_div_u(),
Instruction::i32_rem_s(),
Instruction::i32_rem_u(),
Instruction::i32_and(),
Instruction::i32_or(),
Instruction::i32_xor(),
Instruction::i32_shl(),
Instruction::i32_shr_s(),
Instruction::i32_shr_u(),
Instruction::i32_rotl(),
Instruction::i32_rotr(),
]
for op in i32_binary_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i32_const(I32(84)),
Instruction::i32_const(I32(3)),
op,
])
}
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i64_const(I64(0L)),
Instruction::i64_eqz(),
])
let i64_unary_ops = [
Instruction::i64_clz(),
Instruction::i64_ctz(),
Instruction::i64_popcnt(),
]
for op in i64_unary_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i64_const(I64(99L)),
op,
])
}
let i64_cmp_ops = [
Instruction::i64_eq(),
Instruction::i64_ne(),
Instruction::i64_lt_s(),
Instruction::i64_lt_u(),
Instruction::i64_gt_s(),
Instruction::i64_gt_u(),
Instruction::i64_le_s(),
Instruction::i64_le_u(),
Instruction::i64_ge_s(),
Instruction::i64_ge_u(),
]
for op in i64_cmp_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i64_const(I64(99L)),
Instruction::i64_const(I64(5L)),
op,
])
}
let i64_int_ops = [
Instruction::i64_add(),
Instruction::i64_sub(),
Instruction::i64_mul(),
Instruction::i64_div_s(),
Instruction::i64_div_u(),
Instruction::i64_rem_s(),
Instruction::i64_rem_u(),
Instruction::i64_and(),
Instruction::i64_or(),
Instruction::i64_xor(),
]
for op in i64_int_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i64_const(I64(99L)),
Instruction::i64_const(I64(5L)),
op,
])
}
let i64_shift_ops = [
Instruction::i64_shl(),
Instruction::i64_shr_s(),
Instruction::i64_shr_u(),
Instruction::i64_rotl(),
Instruction::i64_rotr(),
]
for op in i64_shift_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i64_const(I64(99L)),
Instruction::i64_const(I64(5L)),
op,
])
}
let f32_unary_ops = [
Instruction::f32_abs(),
Instruction::f32_neg(),
Instruction::f32_ceil(),
Instruction::f32_floor(),
Instruction::f32_trunc(),
Instruction::f32_nearest(),
Instruction::f32_sqrt(),
]
for op in f32_unary_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f32_const(F32(Float::from_double(9.25))),
op,
])
}
let f32_binary_ops = [
Instruction::f32_add(),
Instruction::f32_sub(),
Instruction::f32_mul(),
Instruction::f32_div(),
Instruction::f32_min(),
Instruction::f32_max(),
Instruction::f32_copysign(),
]
for op in f32_binary_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f32_const(F32(Float::from_double(9.25))),
Instruction::f32_const(F32(Float::from_double(2.5))),
op,
])
}
let f32_cmp_ops = [
Instruction::f32_eq(),
Instruction::f32_ne(),
Instruction::f32_lt(),
Instruction::f32_gt(),
Instruction::f32_le(),
Instruction::f32_ge(),
]
for op in f32_cmp_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f32_const(F32(Float::from_double(9.25))),
Instruction::f32_const(F32(Float::from_double(2.5))),
op,
])
}
let f64_unary_ops = [
Instruction::f64_abs(),
Instruction::f64_neg(),
Instruction::f64_ceil(),
Instruction::f64_floor(),
Instruction::f64_trunc(),
Instruction::f64_nearest(),
Instruction::f64_sqrt(),
]
for op in f64_unary_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f64_const(F64(16.75)),
op,
])
}
let f64_binary_ops = [
Instruction::f64_add(),
Instruction::f64_sub(),
Instruction::f64_mul(),
Instruction::f64_div(),
Instruction::f64_min(),
Instruction::f64_max(),
Instruction::f64_copysign(),
]
for op in f64_binary_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f64_const(F64(16.75)),
Instruction::f64_const(F64(4.5)),
op,
])
}
let f64_cmp_ops = [
Instruction::f64_eq(),
Instruction::f64_ne(),
Instruction::f64_lt(),
Instruction::f64_gt(),
Instruction::f64_le(),
Instruction::f64_ge(),
]
for op in f64_cmp_ops {
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f64_const(F64(16.75)),
Instruction::f64_const(F64(4.5)),
op,
])
}
let conversion_ops = [
[Instruction::i64_const(I64(12L)), Instruction::i32_wrap_i64()],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::i32_trunc_f32s(),
],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::i32_trunc_f32u(),
],
[Instruction::f64_const(F64(12.0)), Instruction::i32_trunc_f64s()],
[Instruction::f64_const(F64(12.0)), Instruction::i32_trunc_f64u()],
[Instruction::i32_const(I32(12)), Instruction::i64_extend_i32s()],
[Instruction::i32_const(I32(12)), Instruction::i64_extend_i32u()],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::i64_trunc_f32s(),
],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::i64_trunc_f32u(),
],
[Instruction::f64_const(F64(12.0)), Instruction::i64_trunc_f64s()],
[Instruction::f64_const(F64(12.0)), Instruction::i64_trunc_f64u()],
[Instruction::i32_const(I32(12)), Instruction::f32_convert_i32s()],
[Instruction::i32_const(I32(12)), Instruction::f32_convert_i32u()],
[Instruction::i64_const(I64(12L)), Instruction::f32_convert_i64s()],
[Instruction::i64_const(I64(12L)), Instruction::f32_convert_i64u()],
[Instruction::f64_const(F64(12.0)), Instruction::f32_demote_f64()],
[Instruction::i32_const(I32(12)), Instruction::f64_convert_i32s()],
[Instruction::i32_const(I32(12)), Instruction::f64_convert_i32u()],
[Instruction::i64_const(I64(12L)), Instruction::f64_convert_i64s()],
[Instruction::i64_const(I64(12L)), Instruction::f64_convert_i64u()],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::f64_promote_f32(),
],
[Instruction::i32_const(I32(0x7f)), Instruction::i32_extend8s()],
[Instruction::i32_const(I32(0x7fff)), Instruction::i32_extend16s()],
[Instruction::i64_const(I64(0x7fL)), Instruction::i64_extend8s()],
[Instruction::i64_const(I64(0x7fffL)), Instruction::i64_extend16s()],
[Instruction::i64_const(I64(0x7fffffffL)), Instruction::i64_extend32s()],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::i32_trunc_sat_f32s(),
],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::i32_trunc_sat_f32u(),
],
[Instruction::f64_const(F64(12.0)), Instruction::i32_trunc_sat_f64s()],
[Instruction::f64_const(F64(12.0)), Instruction::i32_trunc_sat_f64u()],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::i64_trunc_sat_f32s(),
],
[
Instruction::f32_const(F32(Float::from_double(12.0))),
Instruction::i64_trunc_sat_f32u(),
],
[Instruction::f64_const(F64(12.0)), Instruction::i64_trunc_sat_f64s()],
[Instruction::f64_const(F64(12.0)), Instruction::i64_trunc_sat_f64u()],
[
Instruction::f32_const(F32(Float::from_double(1.0))),
Instruction::i32_reinterpret_f32(),
],
[Instruction::f64_const(F64(1.0)), Instruction::i64_reinterpret_f64()],
[
Instruction::i32_const(I32(0x3f800000)),
Instruction::f32_reinterpret_i32(),
],
[
Instruction::i64_const(I64(0x3ff0000000000000L)),
Instruction::f64_reinterpret_i64(),
],
]
for instrs in conversion_ops {
gen_valid_append_scalar_numeric_drop(out, instrs)
}
gen_valid_append_scalar_numeric_drop(out, [
Instruction::i32_const(I32(6)),
Instruction::i32_const(I32(7)),
Instruction::i32_add(),
Instruction::i32_const(I32(3)),
Instruction::i32_mul(),
])
gen_valid_append_scalar_numeric_drop(out, [
Instruction::f64_const(F64(6.5)),
Instruction::f64_const(F64(2.0)),
Instruction::f64_div(),
Instruction::f64_const(F64(1.5)),
Instruction::f64_sub(),
])
}
///|
fn gen_valid_append_basic_ref_is_null(
out : Array[Instruction],
ht : HeapType,
) -> Unit {
out.push(Instruction::ref_null(ht))
out.push(Instruction::ref_is_null())
out.push(Instruction::drop())
}
///|
fn gen_valid_append_basic_ref_test_cast_pair(
out : Array[Instruction],
source_ht : HeapType,
target_ht : HeapType,
target_nullable : Bool,
) -> Unit {
out.push(Instruction::ref_null(source_ht))
out.push(Instruction::ref_test(target_nullable, target_ht))
out.push(Instruction::drop())
out.push(Instruction::ref_null(source_ht))
out.push(Instruction::ref_cast(target_nullable, target_ht))
out.push(Instruction::drop())
}
///|
fn gen_valid_append_basic_ref_br_on_cast_pair(
out : Array[Instruction],
source_nullable : Bool,
target_nullable : Bool,
) -> Unit {
let any = HeapType::abs(AbsHeapType::any())
let i31 = HeapType::abs(AbsHeapType::i31())
let block_ref = RefType::new(source_nullable, any)
let source_instrs : Array[Instruction] = [Instruction::ref_null(any)]
if !source_nullable {
source_instrs.push(Instruction::ref_as_non_null())
}
source_instrs.push(
Instruction::br_on_cast(
LabelIdx::new(0U),
source_nullable,
any,
target_nullable,
i31,
),
)
out.push(
Instruction::block(
BlockType::val_type(ValType::ref_type(block_ref)),
Expr::new(source_instrs),
),
)
out.push(Instruction::drop())
let fail_instrs : Array[Instruction] = [Instruction::ref_null(any)]
if !source_nullable {
fail_instrs.push(Instruction::ref_as_non_null())
}
fail_instrs.push(
Instruction::br_on_cast_fail(
LabelIdx::new(0U),
source_nullable,
any,
target_nullable,
i31,
),
)
out.push(
Instruction::block(
BlockType::val_type(ValType::ref_type(block_ref)),
Expr::new(fail_instrs),
),
)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_basic_ref_ops(
out : Array[Instruction],
ctx : GenValidContext,
) -> Unit {
if !ctx.config.features.allow_ref_types {
return
}
let any = HeapType::abs(AbsHeapType::any())
gen_valid_append_basic_ref_is_null(out, any)
gen_valid_append_basic_ref_is_null(out, HeapType::abs(AbsHeapType::none()))
gen_valid_append_basic_ref_is_null(out, HeapType::abs(AbsHeapType::no_func()))
gen_valid_append_basic_ref_is_null(
out,
HeapType::abs(AbsHeapType::no_extern()),
)
gen_valid_append_basic_ref_test_cast_pair(out, any, any, true)
gen_valid_append_basic_ref_test_cast_pair(out, any, any, false)
gen_valid_append_basic_ref_br_on_cast_pair(out, true, true)
gen_valid_append_basic_ref_br_on_cast_pair(out, true, false)
gen_valid_append_basic_ref_br_on_cast_pair(out, false, false)
}
///|
fn gen_valid_append_i31_extern_conversion_ops(
out : Array[Instruction],
ctx : GenValidContext,
) -> Unit {
if !ctx.config.features.allow_ref_types {
return
}
out.push(Instruction::i32_const(I32(7)))
out.push(Instruction::ref_i31())
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(8)))
out.push(Instruction::ref_i31())
out.push(Instruction::i31_get_s())
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(9)))
out.push(Instruction::ref_i31())
out.push(Instruction::i31_get_u())
out.push(Instruction::drop())
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::extern_())))
out.push(Instruction::any_convert_extern())
out.push(Instruction::extern_convert_any())
out.push(Instruction::drop())
}
///|
fn gen_valid_try_table_has_exception_matrix(catches : Array[Catch]) -> Bool {
let mut has_catch = false
let mut has_catch_ref = false
let mut has_catch_all = false
let mut has_catch_all_ref = false
for catch_ in catches {
match catch_ {
Catch(_, _) => has_catch = true
CatchRef(_, _) => has_catch_ref = true
CatchAll(_) => has_catch_all = true
CatchAllRef(_) => has_catch_all_ref = true
}
}
(has_catch && has_catch_all) || (has_catch_ref && has_catch_all_ref)
}
///|
fn gen_valid_first_payload_tag(tags : Array[TagType]) -> TagIdx? {
for i = 0; i < tags.length(); i = i + 1 {
let TagType(candidate) = tags[i]
if candidate != TypeIdx::new(0U) {
return Some(TagIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_valid_append_exception_try_table_matrix_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !ctx.config.features.allow_ref_types || env.tags.is_empty() {
return
}
let tag_idx = TagIdx::new(0U)
let payload_tag_idx = match gen_valid_first_payload_tag(env.tags) {
Some(idx) => idx
None => tag_idx
}
let exnref = ValType::ref_type(
RefType::new(false, HeapType::abs(AbsHeapType::exn())),
)
let exn_local = gen_matching_local_idx(
env.local_types,
ValType::ref_null_exn(),
)
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[
Catch::new(tag_idx, LabelIdx::new(0U)),
Catch::all(LabelIdx::new(0U)),
],
Expr::new([
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
Instruction::if_(
BlockType::void_(),
[Instruction::throw_(tag_idx)],
Some([
Instruction::ref_null(HeapType::abs(AbsHeapType::exn())),
Instruction::throw_ref(),
]),
),
]),
),
]),
),
)
out.push(
Instruction::block(
BlockType::val_type(exnref),
Expr::new([
Instruction::try_table(
BlockType::val_type(exnref),
[
Catch::ref_(tag_idx, LabelIdx::new(0U)),
Catch::all_ref(LabelIdx::new(0U)),
],
Expr::new([Instruction::throw_(tag_idx)]),
),
]),
),
)
out.push(Instruction::drop())
if payload_tag_idx != tag_idx {
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[Catch::new(payload_tag_idx, LabelIdx::new(0U))],
Expr::new([
Instruction::i32_const(I32(42)),
Instruction::throw_(payload_tag_idx),
]),
),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[
Catch::new(tag_idx, LabelIdx::new(0U)),
Catch::all(LabelIdx::new(0U)),
Catch::new(payload_tag_idx, LabelIdx::new(1U)),
],
Expr::new([
Instruction::i32_const(I32(77)),
Instruction::throw_(payload_tag_idx),
]),
),
]),
),
Instruction::i32_const(I32(0)),
]),
),
)
out.push(Instruction::drop())
}
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([Instruction::i32_const(I32(5))]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::new(tag_idx, LabelIdx::new(0U))],
Expr::new([Instruction::throw_(tag_idx)]),
),
]),
),
]),
),
)
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::ref_null_exn()),
Expr::new([Instruction::ref_null(HeapType::abs(AbsHeapType::exn()))]),
),
Instruction::throw_ref(),
]),
),
)
match exn_local {
Some(local_idx) =>
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::exn())),
Instruction::local_set(local_idx),
Instruction::local_get(local_idx),
Instruction::throw_ref(),
]),
),
)
None => ()
}
}
///|
fn gen_valid_append_v128_zero(out : Array[Instruction]) -> Unit {
out.push(
Instruction::v128_const(
b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00',
b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00', b'\x00',
),
)
}
///|
fn gen_valid_append_v128_binary_op(
out : Array[Instruction],
instr : Instruction,
) -> Unit {
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
out.push(instr)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_v128_unary_op(
out : Array[Instruction],
instr : Instruction,
) -> Unit {
gen_valid_append_v128_zero(out)
out.push(instr)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_v128_ternary_op(
out : Array[Instruction],
instr : Instruction,
) -> Unit {
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
out.push(instr)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_v128_shift_op(
out : Array[Instruction],
amount : Int32,
instr : Instruction,
) -> Unit {
gen_valid_append_v128_zero(out)
out.push(Instruction::i32_const(I32(amount)))
out.push(instr)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_simd_lane_index_coverage(out : Array[Instruction]) -> Unit {
gen_valid_append_v128_zero(out)
out.push(Instruction::i8x16_extract_lane_s(LaneIdx::new(8)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i32_const(I32(15)))
out.push(Instruction::i8x16_replace_lane(LaneIdx::new(15)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i16x8_extract_lane_s(LaneIdx::new(0)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i32_const(I32(16)))
out.push(Instruction::i16x8_replace_lane(LaneIdx::new(7)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i32x4_extract_lane(LaneIdx::new(0)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::f32x4_extract_lane(LaneIdx::new(2)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i32_const(I32(17)))
out.push(Instruction::i32x4_replace_lane(LaneIdx::new(3)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i64x2_extract_lane(LaneIdx::new(0)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::f64x2_extract_lane(LaneIdx::new(1)))
out.push(Instruction::drop())
}
///|
fn gen_valid_append_relaxed_simd_ops(out : Array[Instruction]) -> Unit {
gen_valid_append_v128_binary_op(out, Instruction::i8x16_relaxed_swizzle())
gen_valid_append_v128_ternary_op(out, Instruction::i8x16_relaxed_laneselect())
gen_valid_append_v128_ternary_op(out, Instruction::i16x8_relaxed_laneselect())
gen_valid_append_v128_ternary_op(out, Instruction::i32x4_relaxed_laneselect())
gen_valid_append_v128_ternary_op(out, Instruction::i64x2_relaxed_laneselect())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_relaxed_trunc_f32x4s())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_relaxed_trunc_f32x4u())
gen_valid_append_v128_unary_op(
out,
Instruction::i32x4_relaxed_trunc_zero_f64x2s(),
)
gen_valid_append_v128_unary_op(
out,
Instruction::i32x4_relaxed_trunc_zero_f64x2u(),
)
gen_valid_append_v128_ternary_op(out, Instruction::f32x4_relaxed_madd())
gen_valid_append_v128_ternary_op(out, Instruction::f32x4_relaxed_nmadd())
gen_valid_append_v128_ternary_op(out, Instruction::f64x2_relaxed_madd())
gen_valid_append_v128_ternary_op(out, Instruction::f64x2_relaxed_nmadd())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_relaxed_min())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_relaxed_max())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_relaxed_min())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_relaxed_max())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_relaxed_q15mulr_s())
gen_valid_append_v128_binary_op(
out,
Instruction::i16x8_relaxed_dot_i8x16i7x16s(),
)
gen_valid_append_v128_ternary_op(
out,
Instruction::i32x4_relaxed_dot_i8x16i7x16_add_s(),
)
}
///|
fn gen_valid_append_simd_phase1_ops(out : Array[Instruction]) -> Unit {
gen_valid_append_v128_zero(out)
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(7)))
out.push(Instruction::i8x16_splat())
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(300)))
out.push(Instruction::i16x8_splat())
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(12345)))
out.push(Instruction::i32x4_splat())
out.push(Instruction::drop())
out.push(Instruction::i64_const(I64(123456L)))
out.push(Instruction::i64x2_splat())
out.push(Instruction::drop())
out.push(Instruction::f32_const(F32(Float::from_double(1.5))))
out.push(Instruction::f32x4_splat())
out.push(Instruction::drop())
out.push(Instruction::f64_const(F64(2.5)))
out.push(Instruction::f64x2_splat())
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i8x16_extract_lane_s(LaneIdx::new(0)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i8x16_extract_lane_u(LaneIdx::new(1)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i32_const(I32(9)))
out.push(Instruction::i8x16_replace_lane(LaneIdx::new(2)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i16x8_extract_lane_s(LaneIdx::new(3)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i16x8_extract_lane_u(LaneIdx::new(4)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i32_const(I32(10)))
out.push(Instruction::i16x8_replace_lane(LaneIdx::new(5)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i32x4_extract_lane(LaneIdx::new(1)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i32_const(I32(11)))
out.push(Instruction::i32x4_replace_lane(LaneIdx::new(2)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i64x2_extract_lane(LaneIdx::new(1)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::i64_const(I64(12L)))
out.push(Instruction::i64x2_replace_lane(LaneIdx::new(0)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::f32x4_extract_lane(LaneIdx::new(2)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::f32_const(F32(Float::from_double(3.5))))
out.push(Instruction::f32x4_replace_lane(LaneIdx::new(3)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::f64x2_extract_lane(LaneIdx::new(1)))
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::f64_const(F64(4.5)))
out.push(Instruction::f64x2_replace_lane(LaneIdx::new(0)))
out.push(Instruction::drop())
gen_valid_append_simd_lane_index_coverage(out)
gen_valid_append_v128_zero(out)
out.push(Instruction::v128_not())
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
out.push(Instruction::v128_and())
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
out.push(Instruction::v128_andnot())
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
out.push(Instruction::v128_or())
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
out.push(Instruction::v128_xor())
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
gen_valid_append_v128_zero(out)
out.push(Instruction::v128_bitselect())
out.push(Instruction::drop())
gen_valid_append_v128_zero(out)
out.push(Instruction::v128_any_true())
out.push(Instruction::drop())
}
///|
fn gen_valid_append_simd_phase2_ops(out : Array[Instruction]) -> Unit {
gen_valid_append_v128_binary_op(out, Instruction::i8x16_eq())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_ne())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_lt_s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_lt_u())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_gt_s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_gt_u())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_le_s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_le_u())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_ge_s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_ge_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_eq())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_ne())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_lt_s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_lt_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_gt_s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_gt_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_le_s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_le_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_ge_s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_ge_u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_eq())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_ne())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_lt_s())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_lt_u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_gt_s())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_gt_u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_le_s())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_le_u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_ge_s())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_ge_u())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_eq())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_ne())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_lt_s())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_gt_s())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_le_s())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_ge_s())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_eq())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_ne())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_lt())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_gt())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_le())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_ge())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_eq())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_ne())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_lt())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_gt())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_le())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_ge())
gen_valid_append_v128_unary_op(out, Instruction::i8x16_abs())
gen_valid_append_v128_unary_op(out, Instruction::i8x16_neg())
gen_valid_append_v128_unary_op(out, Instruction::i8x16_popcnt())
gen_valid_append_v128_unary_op(out, Instruction::i8x16_all_true())
gen_valid_append_v128_unary_op(out, Instruction::i8x16_bitmask())
gen_valid_append_v128_unary_op(out, Instruction::i16x8_abs())
gen_valid_append_v128_unary_op(out, Instruction::i16x8_neg())
gen_valid_append_v128_binary_op(out, Instruction::i16x8q15mulr_sat_s())
gen_valid_append_v128_unary_op(out, Instruction::i16x8_all_true())
gen_valid_append_v128_unary_op(out, Instruction::i16x8_bitmask())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_abs())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_neg())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_bitmask())
gen_valid_append_v128_unary_op(out, Instruction::i64x2_abs())
gen_valid_append_v128_unary_op(out, Instruction::i64x2_neg())
gen_valid_append_v128_unary_op(out, Instruction::i64x2_all_true())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_all_true())
gen_valid_append_v128_unary_op(out, Instruction::i64x2_bitmask())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_add())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_add_sat_s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_add_sat_u())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_sub())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_sub_sat_s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_sub_sat_u())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_min_s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_min_u())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_max_s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_max_u())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_avgr_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_mul())
gen_valid_append_v128_shift_op(out, 1, Instruction::i8x16_shl())
gen_valid_append_v128_shift_op(out, 2, Instruction::i8x16_shr_s())
gen_valid_append_v128_shift_op(out, 3, Instruction::i8x16_shr_u())
gen_valid_append_v128_shift_op(out, 4, Instruction::i16x8_shl())
gen_valid_append_v128_shift_op(out, 5, Instruction::i16x8_shr_s())
gen_valid_append_v128_shift_op(out, 6, Instruction::i16x8_shr_u())
gen_valid_append_v128_shift_op(out, 7, Instruction::i32x4_shl())
gen_valid_append_v128_shift_op(out, 8, Instruction::i32x4_shr_s())
gen_valid_append_v128_shift_op(out, 9, Instruction::i32x4_shr_u())
gen_valid_append_v128_shift_op(out, 10, Instruction::i64x2_shl())
gen_valid_append_v128_shift_op(out, 11, Instruction::i64x2_shr_s())
gen_valid_append_v128_shift_op(out, 12, Instruction::i64x2_shr_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_add())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_add_sat_s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_add_sat_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_sub())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_sub_sat_s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_sub_sat_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_min_s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_min_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_max_s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_max_u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_avgr_u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_add())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_sub())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_mul())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_min_s())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_min_u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_max_s())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_max_u())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_add())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_sub())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_mul())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_add())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_abs())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_neg())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_sqrt())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_sub())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_mul())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_div())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_min())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_max())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_pmin())
gen_valid_append_v128_binary_op(out, Instruction::f32x4_pmax())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_add())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_abs())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_neg())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_sqrt())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_sub())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_mul())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_div())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_min())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_max())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_pmin())
gen_valid_append_v128_binary_op(out, Instruction::f64x2_pmax())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_ceil())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_floor())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_trunc())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_nearest())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_ceil())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_floor())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_trunc())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_nearest())
}
///|
fn gen_valid_append_simd_memory_load_drop(
out : Array[Instruction],
load : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
out.push(load)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_simd_memory_lane_load_drop(
out : Array[Instruction],
load : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
gen_valid_append_v128_zero(out)
out.push(load)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_simd_memory_store(
out : Array[Instruction],
store : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
gen_valid_append_v128_zero(out)
out.push(store)
}
///|
fn gen_valid_append_atomic_load_drop(
out : Array[Instruction],
load : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
out.push(load)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_atomic_store(
out : Array[Instruction],
value64 : Bool,
store : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
if value64 {
out.push(Instruction::i64_const(I64(0L)))
} else {
out.push(Instruction::i32_const(I32(0)))
}
out.push(store)
}
///|
fn gen_valid_append_atomic_rmw_drop(
out : Array[Instruction],
value64 : Bool,
instr : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
if value64 {
out.push(Instruction::i64_const(I64(1L)))
} else {
out.push(Instruction::i32_const(I32(1)))
}
out.push(instr)
out.push(Instruction::drop())
}
///|
fn gen_valid_append_atomic_cmpxchg_drop(
out : Array[Instruction],
value64 : Bool,
instr : Instruction,
) -> Unit {
out.push(Instruction::i32_const(I32(0)))
if value64 {
out.push(Instruction::i64_const(I64(1L)))
out.push(Instruction::i64_const(I64(2L)))
} else {
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::i32_const(I32(2)))
}
out.push(instr)
out.push(Instruction::drop())
}
///|
fn gen_valid_atomic_shared_mem_idx(env : GenValidBodyEnv) -> MemIdx? {
for i = 0; i < env.mems.length(); i = i + 1 {
let MemType(_, shared) = env.mems[i]
if shared {
return Some(MemIdx::new(i.reinterpret_as_uint()))
}
}
None
}
///|
fn gen_valid_atomic_memarg(
mem_idx : MemIdx,
align_pow : UInt32,
offset : UInt64,
) -> MemArg {
MemArg::new(U32(align_pow), Some(mem_idx), U64(offset))
}
///|
fn gen_valid_append_atomic_ops(
out : Array[Instruction],
mem_idx : MemIdx,
) -> Unit {
gen_valid_append_atomic_load_drop(
out,
Instruction::i32_atomic_load(gen_valid_atomic_memarg(mem_idx, 2U, 240UL)),
)
gen_valid_append_atomic_load_drop(
out,
Instruction::i64_atomic_load(gen_valid_atomic_memarg(mem_idx, 3U, 248UL)),
)
gen_valid_append_atomic_load_drop(
out,
Instruction::i32_atomic_load8_u(gen_valid_atomic_memarg(mem_idx, 0U, 256UL)),
)
gen_valid_append_atomic_load_drop(
out,
Instruction::i32_atomic_load16_u(
gen_valid_atomic_memarg(mem_idx, 1U, 264UL),
),
)
gen_valid_append_atomic_load_drop(
out,
Instruction::i64_atomic_load8_u(gen_valid_atomic_memarg(mem_idx, 0U, 272UL)),
)
gen_valid_append_atomic_load_drop(
out,
Instruction::i64_atomic_load16_u(
gen_valid_atomic_memarg(mem_idx, 1U, 280UL),
),
)
gen_valid_append_atomic_load_drop(
out,
Instruction::i64_atomic_load32_u(
gen_valid_atomic_memarg(mem_idx, 2U, 288UL),
),
)
gen_valid_append_atomic_store(
out,
false,
Instruction::i32_atomic_store(gen_valid_atomic_memarg(mem_idx, 2U, 296UL)),
)
gen_valid_append_atomic_store(
out,
true,
Instruction::i64_atomic_store(gen_valid_atomic_memarg(mem_idx, 3U, 304UL)),
)
gen_valid_append_atomic_store(
out,
false,
Instruction::i32_atomic_store8(gen_valid_atomic_memarg(mem_idx, 0U, 312UL)),
)
gen_valid_append_atomic_store(
out,
false,
Instruction::i32_atomic_store16(gen_valid_atomic_memarg(mem_idx, 1U, 320UL)),
)
gen_valid_append_atomic_store(
out,
true,
Instruction::i64_atomic_store8(gen_valid_atomic_memarg(mem_idx, 0U, 328UL)),
)
gen_valid_append_atomic_store(
out,
true,
Instruction::i64_atomic_store16(gen_valid_atomic_memarg(mem_idx, 1U, 336UL)),
)
gen_valid_append_atomic_store(
out,
true,
Instruction::i64_atomic_store32(gen_valid_atomic_memarg(mem_idx, 2U, 344UL)),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_add(),
gen_valid_atomic_memarg(mem_idx, 2U, 352UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_add(),
gen_valid_atomic_memarg(mem_idx, 3U, 360UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_8_add_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 368UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_16_add_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 376UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_8_add_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 384UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_16_add_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 392UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_32_add_u(),
gen_valid_atomic_memarg(mem_idx, 2U, 400UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_sub(),
gen_valid_atomic_memarg(mem_idx, 2U, 408UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_sub(),
gen_valid_atomic_memarg(mem_idx, 3U, 416UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_8_sub_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 424UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_16_sub_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 432UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_8_sub_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 440UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_16_sub_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 448UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_32_sub_u(),
gen_valid_atomic_memarg(mem_idx, 2U, 456UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_and(),
gen_valid_atomic_memarg(mem_idx, 2U, 464UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_and(),
gen_valid_atomic_memarg(mem_idx, 3U, 472UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_8_and_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 480UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_16_and_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 488UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_8_and_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 496UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_16_and_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 504UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_32_and_u(),
gen_valid_atomic_memarg(mem_idx, 2U, 512UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_or(),
gen_valid_atomic_memarg(mem_idx, 2U, 520UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_or(),
gen_valid_atomic_memarg(mem_idx, 3U, 528UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_8_or_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 536UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_16_or_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 544UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_8_or_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 552UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_16_or_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 560UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_32_or_u(),
gen_valid_atomic_memarg(mem_idx, 2U, 568UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_xor(),
gen_valid_atomic_memarg(mem_idx, 2U, 576UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_xor(),
gen_valid_atomic_memarg(mem_idx, 3U, 584UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_8_xor_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 592UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_16_xor_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 600UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_8_xor_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 608UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_16_xor_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 616UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_32_xor_u(),
gen_valid_atomic_memarg(mem_idx, 2U, 624UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_xchg(),
gen_valid_atomic_memarg(mem_idx, 2U, 632UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_xchg(),
gen_valid_atomic_memarg(mem_idx, 3U, 640UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_8_xchg_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 648UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
false,
Instruction::atomic_rmw(
AtomicRmwOp::i32_16_xchg_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 656UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_8_xchg_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 664UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_16_xchg_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 672UL),
),
)
gen_valid_append_atomic_rmw_drop(
out,
true,
Instruction::atomic_rmw(
AtomicRmwOp::i64_32_xchg_u(),
gen_valid_atomic_memarg(mem_idx, 2U, 680UL),
),
)
gen_valid_append_atomic_cmpxchg_drop(
out,
false,
Instruction::atomic_cmpxchg(
AtomicCmpxchgOp::i32(),
gen_valid_atomic_memarg(mem_idx, 2U, 688UL),
),
)
gen_valid_append_atomic_cmpxchg_drop(
out,
true,
Instruction::atomic_cmpxchg(
AtomicCmpxchgOp::i64(),
gen_valid_atomic_memarg(mem_idx, 3U, 696UL),
),
)
gen_valid_append_atomic_cmpxchg_drop(
out,
false,
Instruction::atomic_cmpxchg(
AtomicCmpxchgOp::i32_8_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 704UL),
),
)
gen_valid_append_atomic_cmpxchg_drop(
out,
false,
Instruction::atomic_cmpxchg(
AtomicCmpxchgOp::i32_16_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 712UL),
),
)
gen_valid_append_atomic_cmpxchg_drop(
out,
true,
Instruction::atomic_cmpxchg(
AtomicCmpxchgOp::i64_8_u(),
gen_valid_atomic_memarg(mem_idx, 0U, 720UL),
),
)
gen_valid_append_atomic_cmpxchg_drop(
out,
true,
Instruction::atomic_cmpxchg(
AtomicCmpxchgOp::i64_16_u(),
gen_valid_atomic_memarg(mem_idx, 1U, 728UL),
),
)
gen_valid_append_atomic_cmpxchg_drop(
out,
true,
Instruction::atomic_cmpxchg(
AtomicCmpxchgOp::i64_32_u(),
gen_valid_atomic_memarg(mem_idx, 2U, 736UL),
),
)
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(1)))
out.push(
Instruction::memory_atomic_notify(
gen_valid_atomic_memarg(mem_idx, 2U, 744UL),
),
)
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i64_const(I64(0L)))
out.push(
Instruction::memory_atomic_wait32(
gen_valid_atomic_memarg(mem_idx, 2U, 752UL),
),
)
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i64_const(I64(0L)))
out.push(Instruction::i64_const(I64(0L)))
out.push(
Instruction::memory_atomic_wait64(
gen_valid_atomic_memarg(mem_idx, 3U, 760UL),
),
)
out.push(Instruction::drop())
out.push(Instruction::atomic_fence())
}
///|
fn gen_valid_append_simd_phase3_ops(
out : Array[Instruction],
nonzero_mem_idx : MemIdx?,
) -> Unit {
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 4U, 96UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load8x8s(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 112UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load8x8u(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 120UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load16x4s(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 128UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load16x4u(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 136UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load32x2s(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 144UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load32x2u(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 152UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load8_splat(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 0U, 160UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load16_splat(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 1U, 162UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load32_splat(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 2U, 164UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load64_splat(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 168UL),
),
)
gen_valid_append_simd_memory_store(
out,
Instruction::v128_store(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 4U, 176UL),
),
)
gen_valid_append_simd_memory_lane_load_drop(
out,
Instruction::v128_load8_lane(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 0U, 192UL),
LaneIdx::new(3),
),
)
gen_valid_append_simd_memory_lane_load_drop(
out,
Instruction::v128_load16_lane(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 1U, 194UL),
LaneIdx::new(2),
),
)
gen_valid_append_simd_memory_lane_load_drop(
out,
Instruction::v128_load32_lane(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 2U, 196UL),
LaneIdx::new(1),
),
)
gen_valid_append_simd_memory_lane_load_drop(
out,
Instruction::v128_load64_lane(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 200UL),
LaneIdx::new(0),
),
)
gen_valid_append_simd_memory_store(
out,
Instruction::v128_store8_lane(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 0U, 208UL),
LaneIdx::new(4),
),
)
gen_valid_append_simd_memory_store(
out,
Instruction::v128_store16_lane(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 1U, 210UL),
LaneIdx::new(5),
),
)
gen_valid_append_simd_memory_store(
out,
Instruction::v128_store32_lane(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 2U, 212UL),
LaneIdx::new(2),
),
)
gen_valid_append_simd_memory_store(
out,
Instruction::v128_store64_lane(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 216UL),
LaneIdx::new(1),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load32_zero(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 2U, 224UL),
),
)
gen_valid_append_simd_memory_load_drop(
out,
Instruction::v128_load64_zero(
gen_valid_simd_memarg_varied(nonzero_mem_idx, 3U, 232UL),
),
)
gen_valid_append_v128_binary_op(
out,
Instruction::i8x16_shuffle(
LaneIdx::new(0),
LaneIdx::new(17),
LaneIdx::new(2),
LaneIdx::new(19),
LaneIdx::new(4),
LaneIdx::new(21),
LaneIdx::new(6),
LaneIdx::new(23),
LaneIdx::new(8),
LaneIdx::new(25),
LaneIdx::new(10),
LaneIdx::new(27),
LaneIdx::new(12),
LaneIdx::new(29),
LaneIdx::new(14),
LaneIdx::new(31),
),
)
gen_valid_append_v128_binary_op(out, Instruction::i8x16_swizzle())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_narrow_i16x8s())
gen_valid_append_v128_binary_op(out, Instruction::i8x16_narrow_i16x8u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_narrow_i32x4s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_narrow_i32x4u())
gen_valid_append_v128_unary_op(
out,
Instruction::i16x8_extadd_pairwise_i8x16s(),
)
gen_valid_append_v128_unary_op(
out,
Instruction::i16x8_extadd_pairwise_i8x16u(),
)
gen_valid_append_v128_unary_op(
out,
Instruction::i32x4_extadd_pairwise_i16x8s(),
)
gen_valid_append_v128_unary_op(
out,
Instruction::i32x4_extadd_pairwise_i16x8u(),
)
gen_valid_append_v128_unary_op(out, Instruction::i16x8_extend_low_i8x16s())
gen_valid_append_v128_unary_op(out, Instruction::i16x8_extend_high_i8x16s())
gen_valid_append_v128_unary_op(out, Instruction::i16x8_extend_low_i8x16u())
gen_valid_append_v128_unary_op(out, Instruction::i16x8_extend_high_i8x16u())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_extend_low_i16x8s())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_extend_high_i16x8s())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_extend_low_i16x8u())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_extend_high_i16x8u())
gen_valid_append_v128_unary_op(out, Instruction::i64x2_extend_low_i32x4s())
gen_valid_append_v128_unary_op(out, Instruction::i64x2_extend_high_i32x4s())
gen_valid_append_v128_unary_op(out, Instruction::i64x2_extend_low_i32x4u())
gen_valid_append_v128_unary_op(out, Instruction::i64x2_extend_high_i32x4u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_extmul_low_i8x16s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_extmul_high_i8x16s())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_extmul_low_i8x16u())
gen_valid_append_v128_binary_op(out, Instruction::i16x8_extmul_high_i8x16u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_extmul_low_i16x8s())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_extmul_high_i16x8s())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_extmul_low_i16x8u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_extmul_high_i16x8u())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_extmul_low_i32x4s())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_extmul_high_i32x4s())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_extmul_low_i32x4u())
gen_valid_append_v128_binary_op(out, Instruction::i64x2_extmul_high_i32x4u())
gen_valid_append_v128_binary_op(out, Instruction::i32x4_dot_i16x8s())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_demote_f64x2_zero())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_promote_low_f32x4())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_trunc_sat_f32x4s())
gen_valid_append_v128_unary_op(out, Instruction::i32x4_trunc_sat_f32x4u())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_convert_i32x4s())
gen_valid_append_v128_unary_op(out, Instruction::f32x4_convert_i32x4u())
gen_valid_append_v128_unary_op(
out,
Instruction::i32x4_trunc_sat_f64x2s_zero(),
)
gen_valid_append_v128_unary_op(
out,
Instruction::i32x4_trunc_sat_f64x2u_zero(),
)
gen_valid_append_v128_unary_op(out, Instruction::f64x2_convert_low_i32x4s())
gen_valid_append_v128_unary_op(out, Instruction::f64x2_convert_low_i32x4u())
}
///|
fn gen_valid_append_exact_ref_local_flow(
out : Array[Instruction],
env : GenValidBodyEnv,
) -> Unit {
for vt in env.gc_type_plan.exact_ref_types {
match vt {
RefTypeValType(rt) =>
match gen_matching_local_idx(env.local_types, vt) {
Some(idx) => {
out.push(
Instruction::block(
BlockType::val_type(vt),
Expr::new([
Instruction::ref_null_type(rt),
Instruction::local_set(idx),
Instruction::local_get(idx),
]),
),
)
out.push(Instruction::drop())
return
}
None => ()
}
_ => ()
}
}
}
///|
fn gen_valid_append_memory_template_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !env.mems.is_empty() {
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::memory_grow(MemIdx::new(0U)))
out.push(Instruction::drop())
gen_valid_append_scalar_memory_ops(out)
match gen_valid_first_nonzero_i32_mem_idx(env.mems) {
Some(nonzero_mem_idx) =>
gen_valid_append_nonzero_scalar_memory_ops(out, nonzero_mem_idx)
None => ()
}
ignore(gen_valid_append_memory_bulk_ops(out, ctx, env))
}
}
///|
fn gen_valid_append_table_template_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !env.tables.is_empty() {
let TableType(rt, _) = env.tables[0]
out.push(Instruction::table_size(TableIdx::new(0U)))
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(0)))
gen_valid_append_table_ref_value(out, ctx, env, rt)
out.push(Instruction::table_set(TableIdx::new(0U)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::table_get(TableIdx::new(0U)))
out.push(Instruction::drop())
gen_valid_append_table_ref_value(out, ctx, env, rt)
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::table_grow(TableIdx::new(0U)))
out.push(Instruction::drop())
match gen_valid_first_nonzero_table_idx(env.tables) {
Some(nonzero_table_idx) =>
gen_valid_append_nonzero_table_access_ops(out, env, nonzero_table_idx)
None => ()
}
ignore(gen_valid_append_table_bulk_ops(out, ctx, env))
}
}
///|
fn gen_valid_append_global_template_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !env.globals.is_empty() {
out.push(Instruction::global_get(GlobalIdx::new(0U)))
out.push(Instruction::drop())
let GlobalType(first_global_vt, _) = env.globals[0]
match
gen_matching_global_idx(env.globals, first_global_vt, mutable_only=true) {
Some(idx) => {
let GlobalIdx(idx_u) = idx
let GlobalType(vt, _) = env.globals[idx_u.reinterpret_as_int()]
append_value_instrs(
out,
ctx,
vt,
gen_valid_body_env_child(env),
prefer_local=false,
)
out.push(Instruction::global_set(idx))
}
None => ()
}
}
}
///|
fn gen_valid_append_memory_table_global_template_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
let order_key = match env.current_func_idx {
Some(func_idx) => gen_valid_func_idx_to_int(func_idx)
None => env.local_types.length() + env.tables.length() + env.mems.length()
}
let table_first = order_key % 2 == 0
if table_first {
gen_valid_append_table_template_ops(out, ctx, env)
gen_valid_append_memory_template_ops(out, ctx, env)
} else {
gen_valid_append_memory_template_ops(out, ctx, env)
gen_valid_append_table_template_ops(out, ctx, env)
}
gen_valid_append_global_template_ops(out, ctx, env)
}
///|
fn gen_valid_append_simd_template_group(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if !ctx.config.features.allow_v128 {
return
}
if ctx.config.features.allow_relaxed_simd {
gen_valid_append_relaxed_simd_ops(out)
}
let has_memory_phase = !env.mems.is_empty()
let simd_nonzero_mem_idx = gen_valid_first_nonzero_i32_mem_idx(env.mems)
let order_key = match env.current_func_idx {
Some(func_idx) => gen_valid_func_idx_to_int(func_idx)
None => env.local_types.length() + env.tables.length() + env.mems.length()
}
let order_mod = if has_memory_phase { 6 } else { 2 }
match order_key % order_mod {
0 => {
gen_valid_append_simd_phase1_ops(out)
gen_valid_append_simd_phase2_ops(out)
if has_memory_phase {
gen_valid_append_simd_phase3_ops(out, simd_nonzero_mem_idx)
}
}
1 => {
gen_valid_append_simd_phase2_ops(out)
gen_valid_append_simd_phase1_ops(out)
if has_memory_phase {
gen_valid_append_simd_phase3_ops(out, simd_nonzero_mem_idx)
}
}
2 => {
gen_valid_append_simd_phase1_ops(out)
gen_valid_append_simd_phase3_ops(out, simd_nonzero_mem_idx)
gen_valid_append_simd_phase2_ops(out)
}
3 => {
gen_valid_append_simd_phase2_ops(out)
gen_valid_append_simd_phase3_ops(out, simd_nonzero_mem_idx)
gen_valid_append_simd_phase1_ops(out)
}
4 => {
gen_valid_append_simd_phase3_ops(out, simd_nonzero_mem_idx)
gen_valid_append_simd_phase1_ops(out)
gen_valid_append_simd_phase2_ops(out)
}
_ => {
gen_valid_append_simd_phase3_ops(out, simd_nonzero_mem_idx)
gen_valid_append_simd_phase2_ops(out)
gen_valid_append_simd_phase1_ops(out)
}
}
}
///|
fn gen_valid_append_call_template_group(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
returns : Array[ValType],
) -> Unit {
let order_key = gen_valid_template_order_key(env)
match order_key % 3 {
0 => {
gen_valid_append_direct_call_graph_variants(out, ctx, env)
gen_valid_append_call_indirect_variants(out, ctx, env)
gen_valid_append_call_ref_source_variants(out, ctx, env)
}
1 => {
gen_valid_append_call_indirect_variants(out, ctx, env)
gen_valid_append_direct_call_graph_variants(out, ctx, env)
gen_valid_append_call_ref_source_variants(out, ctx, env)
}
_ => {
gen_valid_append_call_ref_source_variants(out, ctx, env)
gen_valid_append_direct_call_graph_variants(out, ctx, env)
gen_valid_append_call_indirect_variants(out, ctx, env)
}
}
gen_valid_append_nested_tail_call_variants(out, ctx, env, returns)
gen_valid_append_tail_call_ops(out, ctx, env, returns)
}
///|
fn gen_valid_template_order_key(env : GenValidBodyEnv) -> Int32 {
match env.current_func_idx {
Some(func_idx) => gen_valid_func_idx_to_int(func_idx)
None =>
env.local_types.length() +
env.tables.length() +
env.mems.length() +
env.funcs.length()
}
}
///|
fn gen_valid_append_ref_template_ops(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
gen_valid_append_exact_ref_local_flow(out, env)
gen_valid_append_basic_ref_ops(out, ctx)
gen_valid_append_i31_extern_conversion_ops(out, ctx)
}
///|
fn gen_valid_append_ref_gc_exception_template_group(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
let order_key = gen_valid_template_order_key(env)
match order_key % 4 {
0 => {
gen_valid_append_gc_prelude(out, ctx, env)
gen_valid_append_ref_template_ops(out, ctx, env)
gen_valid_append_exception_try_table_matrix_ops(out, ctx, env)
}
1 => {
gen_valid_append_ref_template_ops(out, ctx, env)
gen_valid_append_gc_prelude(out, ctx, env)
gen_valid_append_exception_try_table_matrix_ops(out, ctx, env)
}
2 => {
gen_valid_append_exception_try_table_matrix_ops(out, ctx, env)
gen_valid_append_gc_prelude(out, ctx, env)
gen_valid_append_ref_template_ops(out, ctx, env)
}
_ => {
gen_valid_append_exception_try_table_matrix_ops(out, ctx, env)
gen_valid_append_ref_template_ops(out, ctx, env)
gen_valid_append_gc_prelude(out, ctx, env)
}
}
}
///|
fn gen_valid_append_coverage_prelude(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
returns : Array[ValType],
) -> Unit {
gen_valid_append_ref_gc_exception_template_group(out, ctx, env)
gen_valid_append_expanded_scalar_numeric_ops(out, ctx)
gen_valid_append_core_control_ops(out, ctx, env)
gen_valid_append_call_template_group(out, ctx, env, returns)
gen_valid_append_simd_template_group(out, ctx, env)
if ctx.config.features.allow_atomics {
match gen_valid_atomic_shared_mem_idx(env) {
Some(mem_idx) => gen_valid_append_atomic_ops(out, mem_idx)
None => ()
}
}
if ctx.config.features.allow_ref_types {
append_value_instrs(
out,
ctx,
ValType::funcref(),
gen_valid_body_env_child(env),
prefer_local=false,
)
out.push(Instruction::drop())
append_value_instrs(
out,
ctx,
ValType::externref(),
gen_valid_body_env_child(env),
prefer_local=false,
)
out.push(Instruction::drop())
}
if ctx.config.features.allow_calls {
match gen_valid_pick_callable(ctx, env.funcs) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::call(target.idx))
gen_valid_append_call_result_drops(out, target.results)
}
None => ()
}
}
if ctx.config.features.allow_call_indirect && !env.tables.is_empty() {
match gen_valid_pick_callable(ctx, env.funcs) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::call_indirect(target.type_idx, TableIdx::new(0U)))
gen_valid_append_call_result_drops(out, target.results)
}
None => ()
}
}
gen_valid_append_memory_table_global_template_ops(out, ctx, env)
let branch_first = ctx.random_bool_from(BodyStream)
let branch_block_body = [
Instruction::i32_const(I32(if branch_first { 1 } else { 0 })),
Instruction::br_if(LabelIdx::new(0U)),
]
let branch_loop = Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
Instruction::br_if(LabelIdx::new(0U)),
]),
)
let branch_block = Instruction::block(
BlockType::void_(),
Expr::new(branch_block_body),
)
if branch_first {
out.push(branch_block)
out.push(branch_loop)
} else {
out.push(branch_loop)
out.push(branch_block)
}
out.push(
Instruction::i32_const(
I32(if ctx.random_bool_from(BodyStream) { 1 } else { 0 }),
),
)
out.push(
Instruction::if_(
BlockType::void_(),
[
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::br(LabelIdx::new(0U))]),
),
],
Some([Instruction::nop()]),
),
)
}
///|
fn gen_valid_append_return_value_instrs(
out : Array[Instruction],
ctx : GenValidContext,
vt : ValType,
env : GenValidBodyEnv,
) -> Unit {
match vt {
RefTypeValType(rt) if ctx.config.mode == Natural && rt.is_exact() => {
match gen_matching_local_idx(env.local_types, vt) {
Some(idx) => {
out.push(Instruction::local_get(idx))
return
}
None => ()
}
match gen_matching_global_idx(env.globals, vt) {
Some(idx) => {
out.push(Instruction::global_get(idx))
return
}
None => ()
}
if ctx.config.features.allow_ref_types {
match
gen_valid_declared_ref_callable_with_result(
env.funcs,
env.declared_ref_func_idx,
vt,
) {
Some(target) if !ctx.config.features.allow_calls ||
ctx.random_bool_from(BodyStream) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::ref_func(target.idx))
out.push(Instruction::call_ref(target.type_idx))
return
}
_ => ()
}
}
if ctx.config.features.allow_calls {
match gen_valid_pick_callable_with_result(ctx, env.funcs, vt) {
Some(target) => {
gen_valid_append_call_args(out, ctx, env, target.params)
out.push(Instruction::call(target.idx))
return
}
None => ()
}
}
append_value_instrs(out, ctx, vt, env)
}
_ => append_value_instrs(out, ctx, vt, env)
}
}
///|
fn gen_valid_coalesce_locals_has_i32_prefix(
env : GenValidBodyEnv,
count : Int32,
) -> Bool {
if env.local_types.length() < count {
return false
}
for i = 0; i < count; i = i + 1 {
if env.local_types[i] != ValType::i32() {
return false
}
}
true
}
///|
fn gen_valid_append_coalesce_locals_body_slice(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
let exact_types = ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsExactTypesProfile)
if exact_types {
if env.local_types.length() < 4 ||
env.local_types[0] != ValType::i32() ||
env.local_types[1] != ValType::f64() {
return
}
} else if !gen_valid_coalesce_locals_has_i32_prefix(env, 4) {
return
}
let l0 = LocalIdx::new(0U)
let l1 = LocalIdx::new(1U)
let l2 = LocalIdx::new(2U)
if ctx.config == GenValidConfig::for_profile(CoalesceLocalsStructuredProfile) {
out.push(Instruction::i32_const(I32(21)))
out.push(Instruction::local_set(l0))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::local_get(l0),
Instruction::local_set(l1),
Instruction::i32_const(I32(0)),
Instruction::drop(),
Instruction::local_get(l1),
Instruction::local_set(l2),
]),
),
)
out.push(Instruction::local_get(l2))
out.push(Instruction::drop())
} else if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsLoopCopyThroughProfile) {
out.push(
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(44)),
Instruction::local_set(l0),
Instruction::i32_const(I32(5)),
Instruction::drop(),
Instruction::local_get(l0),
Instruction::local_set(l1),
]),
),
)
out.push(Instruction::local_get(l1))
out.push(Instruction::drop())
} else if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsEntryValuesProfile) {
out.append([
Instruction::i32_const(I32(0)),
Instruction::local_set(l0),
Instruction::local_get(l0),
Instruction::drop(),
Instruction::local_get(l1),
Instruction::drop(),
])
} else if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsCopyPreferenceProfile) {
out.append([
Instruction::i32_const(I32(31)),
Instruction::local_set(l0),
Instruction::local_get(l0),
Instruction::local_set(l1),
Instruction::i32_const(I32(7)),
Instruction::drop(),
Instruction::local_get(l1),
Instruction::local_set(l2),
Instruction::local_get(l2),
Instruction::drop(),
])
} else if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsTeeCopiesProfile) {
out.append([
Instruction::i32_const(I32(41)),
Instruction::local_tee(l0),
Instruction::drop(),
Instruction::local_get(l0),
Instruction::local_tee(l1),
Instruction::drop(),
Instruction::local_get(l1),
Instruction::drop(),
])
} else if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsInterBlockProfile) {
out.push(Instruction::i32_const(I32(51)))
out.push(Instruction::local_set(l0))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::local_get(l0), Instruction::local_set(l1)]),
),
)
out.push(Instruction::local_get(l1))
out.push(Instruction::drop())
} else if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsUnreachableProfile) {
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::unreachable_(),
Instruction::local_get(l0),
Instruction::i32_const(I32(0)),
Instruction::local_tee(l0),
Instruction::i32_store(MemArg::new(2U, None, 0UL)),
]),
),
)
} else if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsLegacyEhProfile) {
out.push(
Instruction::try_(
BlockType::void_(),
Expr::new([Instruction::unreachable_()]),
[
@lib.LegacyCatch::all(
Expr::new([Instruction::local_get(l0), Instruction::local_set(l1)]),
),
],
),
)
out.push(Instruction::local_get(l1))
out.push(Instruction::drop())
} else if ctx.config ==
GenValidConfig::for_profile(CoalesceLocalsLargeUnusedProfile) {
out.push(Instruction::local_get(l0))
out.push(Instruction::drop())
} else if exact_types {
out.append([
Instruction::local_get(l0),
Instruction::drop(),
Instruction::local_get(l1),
Instruction::drop(),
])
} else {
out.push(Instruction::i32_const(I32(17)))
out.push(Instruction::local_set(l0))
out.push(Instruction::local_get(l0))
out.push(Instruction::local_set(l1))
out.push(Instruction::local_get(l1))
out.push(Instruction::local_set(l2))
out.push(Instruction::local_get(l2))
out.push(Instruction::drop())
}
}
///|
fn gen_valid_local_subtyping_local(env : GenValidBodyEnv) -> LocalIdx? {
gen_matching_local_idx(env.local_types, ValType::anyref())
}
///|
fn gen_valid_local_subtyping_type(env : GenValidBodyEnv) -> TypeIdx? {
if env.gc_type_plan.struct_type_idxs.is_empty() {
None
} else {
Some(env.gc_type_plan.struct_type_idxs[0])
}
}
///|
fn gen_valid_local_subtyping_seed_local(
out : Array[Instruction],
local_idx : LocalIdx,
type_idx : TypeIdx,
) -> Unit {
out.push(Instruction::struct_new_default(type_idx))
out.push(Instruction::local_set(local_idx))
}
///|
fn gen_valid_local_subtyping_append_get_drop(
out : Array[Instruction],
local_idx : LocalIdx,
) -> Unit {
out.push(Instruction::local_get(local_idx))
out.push(Instruction::drop())
}
///|
fn gen_valid_append_local_subtyping_body_slice(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
let local_idx = match gen_valid_local_subtyping_local(env) {
Some(idx) => idx
None => return
}
let type_idx = match gen_valid_local_subtyping_type(env) {
Some(idx) => idx
None => return
}
if ctx.config == GenValidConfig::for_profile(LocalSubtypingLubsProfile) {
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::ref_i31())
out.push(Instruction::local_set(local_idx))
gen_valid_local_subtyping_seed_local(out, local_idx, type_idx)
gen_valid_local_subtyping_append_get_drop(out, local_idx)
} else if ctx.config ==
GenValidConfig::for_profile(LocalSubtypingIterationProfile) {
let LocalIdx(first_raw) = local_idx
let second = LocalIdx::new(first_raw + 1U)
let third = LocalIdx::new(first_raw + 2U)
gen_valid_local_subtyping_seed_local(out, local_idx, type_idx)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::local_set(second))
out.push(Instruction::local_get(second))
out.push(Instruction::local_set(third))
gen_valid_local_subtyping_append_get_drop(out, third)
} else if ctx.config ==
GenValidConfig::for_profile(LocalSubtypingNullBottomProfile) {
gen_valid_local_subtyping_seed_local(out, local_idx, type_idx)
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::any())))
out.push(Instruction::local_set(local_idx))
gen_valid_local_subtyping_append_get_drop(out, local_idx)
} else if ctx.config ==
GenValidConfig::for_profile(LocalSubtypingControlRefinalizeProfile) {
gen_valid_local_subtyping_seed_local(out, local_idx, type_idx)
out.push(Instruction::i32_const(I32(1)))
out.push(
Instruction::if_(
BlockType::val_type(ValType::anyref()),
[Instruction::i32_const(I32(0)), Instruction::ref_i31()],
Some([Instruction::i32_const(I32(1)), Instruction::ref_i31()]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(ValType::anyref()),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::ref_i31(),
Instruction::br(LabelIdx::new(0U)),
Instruction::i32_const(I32(1)),
Instruction::ref_i31(),
]),
),
)
out.push(Instruction::drop())
gen_valid_local_subtyping_append_get_drop(out, local_idx)
} else {
gen_valid_local_subtyping_seed_local(out, local_idx, type_idx)
if ctx.config ==
GenValidConfig::for_profile(LocalSubtypingUnreachableTailProfile) {
gen_valid_local_subtyping_append_get_drop(out, local_idx)
out.push(Instruction::return_())
gen_valid_local_subtyping_append_get_drop(out, local_idx)
} else if ctx.config ==
GenValidConfig::for_profile(LocalSubtypingStructuredProfile) {
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::local_get(local_idx), Instruction::drop()]),
),
)
out.push(
Instruction::loop_(
BlockType::void_(),
Expr::new([Instruction::local_get(local_idx), Instruction::drop()]),
),
)
out.push(Instruction::i32_const(I32(1)))
out.push(
Instruction::if_(
BlockType::void_(),
[Instruction::local_get(local_idx), Instruction::drop()],
Some([Instruction::local_get(local_idx), Instruction::drop()]),
),
)
gen_valid_local_subtyping_append_get_drop(out, local_idx)
} else {
gen_valid_local_subtyping_append_get_drop(out, local_idx)
out.push(Instruction::struct_new_default(type_idx))
out.push(Instruction::local_tee(local_idx))
out.push(Instruction::drop())
gen_valid_local_subtyping_append_get_drop(out, local_idx)
}
}
}
///|
fn gen_valid_optimize_casts_local(env : GenValidBodyEnv) -> LocalIdx? {
gen_matching_local_idx(env.local_types, ValType::anyref())
}
///|
fn gen_valid_optimize_casts_primary_type(env : GenValidBodyEnv) -> TypeIdx? {
if env.gc_type_plan.struct_type_idxs.is_empty() {
None
} else {
Some(env.gc_type_plan.struct_type_idxs[0])
}
}
///|
fn gen_valid_optimize_casts_secondary_type(env : GenValidBodyEnv) -> TypeIdx? {
if env.gc_type_plan.struct_type_idxs.length() >= 2 {
Some(env.gc_type_plan.struct_type_idxs[1])
} else {
gen_valid_optimize_casts_primary_type(env)
}
}
///|
fn gen_valid_optimize_casts_seed_local(
out : Array[Instruction],
local_idx : LocalIdx,
type_idx : TypeIdx,
) -> Unit {
out.push(Instruction::struct_new_default(type_idx))
out.push(Instruction::local_set(local_idx))
}
///|
fn gen_valid_optimize_casts_append_cast_drop(
out : Array[Instruction],
local_idx : LocalIdx,
nullable : Bool,
type_idx : TypeIdx,
) -> Unit {
out.push(Instruction::local_get(local_idx))
out.push(Instruction::ref_cast(nullable, HeapType::new(type_idx)))
out.push(Instruction::drop())
}
///|
fn gen_valid_append_optimize_casts_body_slice(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
let local_idx = match gen_valid_optimize_casts_local(env) {
Some(idx) => idx
None => return
}
let primary = match gen_valid_optimize_casts_primary_type(env) {
Some(idx) => idx
None => return
}
let secondary = match gen_valid_optimize_casts_secondary_type(env) {
Some(idx) => idx
None => primary
}
gen_valid_optimize_casts_seed_local(out, local_idx, secondary)
let config = ctx.config
if config == GenValidConfig::for_profile(OptimizeCastsLaterReuseProfile) {
gen_valid_optimize_casts_append_cast_drop(out, local_idx, false, secondary)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::drop())
} else if config ==
GenValidConfig::for_profile(OptimizeCastsEarlyMotionProfile) {
out.push(Instruction::local_get(local_idx))
out.push(Instruction::drop())
gen_valid_optimize_casts_append_cast_drop(out, local_idx, false, secondary)
} else if config == GenValidConfig::for_profile(OptimizeCastsBarriersProfile) {
gen_valid_optimize_casts_append_cast_drop(out, local_idx, false, secondary)
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::none())))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::drop())
} else if config == GenValidConfig::for_profile(OptimizeCastsBestCastProfile) {
gen_valid_optimize_casts_append_cast_drop(out, local_idx, false, primary)
gen_valid_optimize_casts_append_cast_drop(out, local_idx, false, secondary)
gen_valid_optimize_casts_append_cast_drop(out, local_idx, false, primary)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::drop())
} else if config == GenValidConfig::for_profile(OptimizeCastsRefAsProfile) {
gen_valid_optimize_casts_append_cast_drop(out, local_idx, true, secondary)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::ref_as_non_null())
out.push(Instruction::drop())
} else if config ==
GenValidConfig::for_profile(OptimizeCastsStaticFoldsProfile) {
out.push(Instruction::local_get(local_idx))
out.push(Instruction::ref_cast(false, HeapType::new(secondary)))
out.push(Instruction::ref_test(false, HeapType::new(secondary)))
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(
Instruction::br_on_cast(
LabelIdx::new(0U),
false,
HeapType::abs(AbsHeapType::any()),
false,
HeapType::new(secondary),
),
)
out.push(Instruction::drop())
} else if config ==
GenValidConfig::for_profile(OptimizeCastsNeighborhoodProfile) {
out.push(Instruction::struct_new_default(secondary))
out.push(Instruction::local_tee(local_idx))
out.push(Instruction::ref_cast(false, HeapType::new(secondary)))
out.push(Instruction::drop())
gen_valid_optimize_casts_append_cast_drop(out, local_idx, false, primary)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::drop())
}
}
///|
fn gen_valid_append_heap2local_body_slice(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
let want_struct = ctx.config ==
GenValidConfig::for_profile(Heap2LocalStructProfile) ||
ctx.config == GenValidConfig::for_profile(Heap2LocalAllProfile)
let want_array = ctx.config ==
GenValidConfig::for_profile(Heap2LocalArrayProfile) ||
ctx.config == GenValidConfig::for_profile(Heap2LocalAllProfile)
let want_ref = ctx.config == GenValidConfig::for_profile(Heap2LocalRefProfile) ||
ctx.config == GenValidConfig::for_profile(Heap2LocalAllProfile)
if want_struct || want_ref {
if !env.gc_type_plan.struct_type_idxs.is_empty() {
let struct_idx = env.gc_type_plan.struct_type_idxs[0]
let struct_ref = ValType::ref_type(
RefType::new(true, HeapType::new(struct_idx)),
)
match gen_matching_local_idx(env.local_types, struct_ref) {
Some(local_idx) => {
if want_struct {
out.push(Instruction::i32_const(I32(10)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(30)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::struct_get(struct_idx, U32::new(0U)))
out.push(Instruction::drop())
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::struct_get(struct_idx, U32::new(0U)))
out.push(Instruction::drop())
}
if want_ref {
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::ref_as_non_null())
out.push(Instruction::struct_get(struct_idx, U32::new(0U)))
out.push(Instruction::drop())
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::ref_eq())
out.push(Instruction::drop())
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::ref_test(false, HeapType::new(struct_idx)))
out.push(Instruction::drop())
}
}
None => ()
}
}
}
if want_array && !env.gc_type_plan.array_type_idxs.is_empty() {
let array_idx = env.gc_type_plan.array_type_idxs[0]
let array_ref = ValType::ref_type(
RefType::new(true, HeapType::new(array_idx)),
)
match gen_matching_local_idx(env.local_types, array_ref) {
Some(local_idx) => {
out.push(Instruction::i32_const(I32(2)))
out.push(Instruction::array_new_default(array_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_get(array_idx))
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(4)))
out.push(Instruction::i32_const(I32(5)))
out.push(Instruction::array_new_fixed(array_idx, U32::new(2U)))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::i32_const(I32(9)))
out.push(Instruction::array_set(array_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::array_get(array_idx))
out.push(Instruction::drop())
}
None => ()
}
}
}
///|
fn gen_valid_append_hso_struct_new_fields(
out : Array[Instruction],
shared : Bool,
first : Int32,
second : Int32,
) -> Unit {
out.push(Instruction::i32_const(I32(first)))
if shared {
out.push(Instruction::i32_const(I32(second)))
} else {
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
}
}
///|
fn gen_valid_append_hso_leaf_body_slice(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
struct_idx : TypeIdx,
local_idx : LocalIdx,
) -> Bool {
let family = ctx.config.max_body_statements
let shared = family == 97
match family {
90 => {
// Immediate local.tee(struct.new) folding.
gen_valid_append_hso_struct_new_fields(out, false, 10, 0)
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_tee(local_idx))
out.push(Instruction::i32_const(I32(11)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::struct_get(struct_idx, U32::new(0U)))
out.push(Instruction::drop())
true
}
91 => {
// Block-local chains and repeated same-field writes.
gen_valid_append_hso_struct_new_fields(out, false, 20, 0)
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(21)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(22)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
true
}
92 => {
// Default-constructor materialization.
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(31)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
true
}
93 => {
// Preserve an overwritten trapping old-field expression while folding.
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(36)),
Instruction::i32_const(I32(3)),
Instruction::i32_div_s(),
]),
),
)
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(41)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
true
}
94 => {
// Descriptor-bearing explicit/default constructor siblings.
match
(
env.gc_type_plan.descriptor_struct_idx,
env.gc_type_plan.descriptor_type_idx,
) {
(Some(described_idx), Some(descriptor_idx)) => {
let described_ref = ValType::ref_type(
RefType::new(true, HeapType::new(described_idx), exact=true),
)
match gen_matching_local_idx(env.local_types, described_ref) {
Some(described_local) => {
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
out.push(Instruction::local_set(described_local))
out.push(Instruction::local_get(described_local))
out.push(Instruction::i32_const(I32(51)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
}
None => ()
}
}
_ => ()
}
true
}
95 => {
// Result-typed control wrapper as the moved store value.
gen_valid_append_hso_struct_new_fields(out, false, 60, 0)
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::i32_const(I32(61))]),
),
)
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
true
}
96 => {
// A readonly root between the constructor local.set and the store.
gen_valid_append_hso_struct_new_fields(out, false, 70, 0)
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::i32_const(I32(71)))
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(72)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
true
}
97 => {
// Release-store directionality against a shared-GC read.
if !env.mems.is_empty() {
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(80)),
Instruction::i32_atomic_store(MemArg::new(2U, None, 0UL)),
Instruction::i32_const(I32(0)),
]),
),
)
out.push(Instruction::i32_const(I32(81)))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::struct_get(struct_idx, U32::new(1U)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
true
}
98 => {
// A write barrier that intentionally terminates the local constructor chain.
gen_valid_append_hso_struct_new_fields(out, false, 90, 0)
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
if !env.mems.is_empty() {
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::memory_grow(MemIdx::new(0U)))
out.push(Instruction::drop())
}
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(91)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
true
}
_ => {
ignore(shared)
false
}
}
}
///|
fn gen_valid_append_heap_store_optimization_body_slice(
out : Array[Instruction],
ctx : GenValidContext,
env : GenValidBodyEnv,
) -> Unit {
if env.gc_type_plan.struct_type_idxs.is_empty() {
return
}
let struct_idx = env.gc_type_plan.struct_type_idxs[0]
let struct_ref = ValType::ref_type(
RefType::new(true, HeapType::new(struct_idx)),
)
let local_idx = match gen_matching_local_idx(env.local_types, struct_ref) {
Some(idx) => idx
None => return
}
if gen_valid_append_hso_leaf_body_slice(out, ctx, env, struct_idx, local_idx) {
return
}
// Subsequent local-get store: the core Binaryen HSO block-local fold.
out.push(Instruction::i32_const(I32(11)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(22)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Tee-root store: the immediate local.tee(struct.new) fold family.
out.push(Instruction::i32_const(I32(33)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_tee(local_idx))
out.push(Instruction::i32_const(I32(44)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::struct_get(struct_idx, U32::new(0U)))
out.push(Instruction::drop())
// Repeated stores keep the final value and exercise same-chain cleanup.
out.push(Instruction::i32_const(I32(55)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(66)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(77)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Call-containing old-field roots exercise preservation of overwritten
// field side effects while still allowing the later same-field store to be
// folded when the call itself is kept before the rewritten constructor.
match env.current_func_idx {
Some(call_idx) =>
match gen_valid_callable_by_idx(env.funcs, call_idx) {
Some(target) if target.params.is_empty() && target.results.is_empty() => {
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::call(call_idx),
Instruction::i32_const(I32(137)),
]),
),
)
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(138)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
_ => ()
}
_ => ()
}
// True call-result old-field roots exercise preservation of an overwritten
// direct call whose result is the actual constructor field value, not the
// value-block approximation above.
let mut i32_result_call : GenValidFuncSig? = None
for func in env.funcs {
if i32_result_call is None &&
func.params.is_empty() &&
func.results == [ValType::i32()] {
i32_result_call = Some(func)
}
}
match i32_result_call {
Some(target) => {
out.push(Instruction::call(target.idx))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(140)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
if !env.tables.is_empty() {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::call_indirect(target.type_idx, TableIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(141)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
out.push(Instruction::ref_func(target.idx))
out.push(Instruction::call_ref(target.type_idx))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(142)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Result-typed direct tail-call wrappers keep generated coverage on the
// source-backed tail-call old-field boundary: the constructor old field
// is a true call result, and the later store remains after a
// result-typed wrapper whose body exits through return_call.
match env.current_func_idx {
Some(tail_idx) =>
match gen_valid_callable_by_idx(env.funcs, tail_idx) {
Some(tail_target) if tail_target.params.is_empty() &&
tail_target.results.is_empty() => {
out.push(Instruction::call(target.idx))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([Instruction::return_call(tail_target.idx)]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(147)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
if !env.tables.is_empty() {
out.push(Instruction::call(target.idx))
out.push(
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
)
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::return_call_indirect(
tail_target.type_idx,
TableIdx::new(0U),
),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(148)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
out.push(Instruction::call(target.idx))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::ref_func(tail_target.idx),
Instruction::return_call_ref(tail_target.type_idx),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(149)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
_ => ()
}
None => ()
}
}
None => ()
}
// Default constructors exercise HSO's materialization path, where a later
// struct.set replaces one default field in the generated struct.new.
out.push(Instruction::struct_new_default(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(88)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::local_get(local_idx))
out.push(Instruction::struct_get(struct_idx, U32::new(0U)))
out.push(Instruction::drop())
// Descriptor-bearing constructors exercise the custom-descriptor siblings of
// HSO's default and explicit-field materialization paths.
match
(
env.gc_type_plan.descriptor_struct_idx,
env.gc_type_plan.descriptor_type_idx,
) {
(Some(described_idx), Some(descriptor_idx)) => {
let described_ref = ValType::ref_type(
RefType::new(true, HeapType::new(described_idx), exact=true),
)
match gen_matching_local_idx(env.local_types, described_ref) {
Some(described_local_idx) => {
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_default_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(89)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
out.push(Instruction::i32_const(I32(90)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(91)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::struct_get(described_idx, U32::new(0U)))
out.push(Instruction::drop())
// Descriptor result-typed try_table set values exercise the dropped
// result-wrapper fold family without requiring the broader generated
// call surfaces. The wrapper produces the moved same-field value.
out.push(Instruction::i32_const(I32(110)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([Instruction::i32_const(I32(111))]),
),
)
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
// Descriptor later-field result wrappers exercise folds where a
// different constructor field is supplied by a result-typed
// try_table and the later same-field store still targets field 0.
out.push(Instruction::i32_const(I32(112)))
out.push(
Instruction::try_table(
BlockType::val_type(
ValType::ref_type(RefType::abs(AbsHeapType::eq())),
),
[],
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
]),
),
)
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(113)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
// Descriptor old-field side-effect preservation: a later same-field
// store can fold into struct.new_desc only if the overwritten
// memory.grow field effect is preserved in order.
if !env.mems.is_empty() {
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::memory_grow(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(109)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
}
// Descriptor call-result old-field roots cover the descriptor-bearing
// sibling of the plain direct-call result root above: the overwritten
// field is the direct helper call result, and the descriptor is pure.
match i32_result_call {
Some(target) => {
out.push(Instruction::call(target.idx))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(143)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
if !env.tables.is_empty() {
out.push(Instruction::i32_const(I32(0)))
out.push(
Instruction::call_indirect(target.type_idx, TableIdx::new(0U)),
)
out.push(
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
)
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(145)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
}
out.push(Instruction::ref_func(target.idx))
out.push(Instruction::call_ref(target.type_idx))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(146)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
// Descriptor tail-call result-wrapper old-field roots keep the
// generated profile on the pure-descriptor siblings of the plain
// tail-call family: the overwritten field is a true helper call
// result, the descriptor operand is pure, and the later same-
// field store remains after the result-typed wrapper.
match env.current_func_idx {
Some(tail_idx) =>
match gen_valid_callable_by_idx(env.funcs, tail_idx) {
Some(tail_target) if tail_target.params.is_empty() &&
tail_target.results.is_empty() => {
out.push(Instruction::call(target.idx))
out.push(
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
)
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([Instruction::return_call(tail_target.idx)]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(150)))
out.push(
Instruction::struct_set(described_idx, U32::new(0U)),
)
if !env.tables.is_empty() {
out.push(Instruction::call(target.idx))
out.push(
Instruction::ref_null(
HeapType::abs(AbsHeapType::eq()),
),
)
out.push(
Instruction::struct_new_default(descriptor_idx),
)
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::return_call_indirect(
tail_target.type_idx,
TableIdx::new(0U),
),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(151)))
out.push(
Instruction::struct_set(described_idx, U32::new(0U)),
)
}
out.push(Instruction::call(target.idx))
out.push(
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
)
out.push(Instruction::struct_new_default(descriptor_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::ref_func(tail_target.idx),
Instruction::return_call_ref(tail_target.type_idx),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(152)))
out.push(
Instruction::struct_set(described_idx, U32::new(0U)),
)
}
_ => ()
}
None => ()
}
// Mutable-descriptor direct-call result roots keep the generated
// surface distinct from pure descriptor calls and from the older
// result-wrapper barrier roots: the overwritten field is the
// helper call result while the constructor descriptor is read
// from a mutable descriptor global.
let descriptor_ref = ValType::ref_type(
RefType::new(true, HeapType::new(descriptor_idx), exact=true),
)
match
gen_matching_global_idx(
env.globals,
descriptor_ref,
mutable_only=true,
) {
Some(desc_global_idx) => {
out.push(Instruction::call(target.idx))
out.push(
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
)
out.push(Instruction::global_get(desc_global_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(144)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
// Mutable-descriptor direct tail-call result-wrapper roots
// add the tail-call sibling of marker 144: the overwritten
// field is the helper call result, the descriptor operand is
// a mutable exact-descriptor global read, and the result
// wrapper exits through return_call before the later store.
match env.current_func_idx {
Some(tail_idx) =>
match gen_valid_callable_by_idx(env.funcs, tail_idx) {
Some(tail_target) if tail_target.params.is_empty() &&
tail_target.results.is_empty() => {
out.push(Instruction::call(target.idx))
out.push(
Instruction::ref_null(
HeapType::abs(AbsHeapType::eq()),
),
)
out.push(Instruction::global_get(desc_global_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::return_call(tail_target.idx),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(153)))
out.push(
Instruction::struct_set(described_idx, U32::new(0U)),
)
if !env.tables.is_empty() {
out.push(Instruction::call(target.idx))
out.push(
Instruction::ref_null(
HeapType::abs(AbsHeapType::eq()),
),
)
out.push(Instruction::global_get(desc_global_idx))
out.push(
Instruction::struct_new_desc(described_idx),
)
out.push(
Instruction::local_set(described_local_idx),
)
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::return_call_indirect(
tail_target.type_idx,
TableIdx::new(0U),
),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::local_get(described_local_idx),
)
out.push(Instruction::i32_const(I32(154)))
out.push(
Instruction::struct_set(
described_idx,
U32::new(0U),
),
)
}
out.push(Instruction::call(target.idx))
out.push(
Instruction::ref_null(
HeapType::abs(AbsHeapType::eq()),
),
)
out.push(Instruction::global_get(desc_global_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::ref_func(tail_target.idx),
Instruction::return_call_ref(
tail_target.type_idx,
),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(155)))
out.push(
Instruction::struct_set(described_idx, U32::new(0U)),
)
}
_ => ()
}
None => ()
}
}
None => ()
}
}
None => ()
}
// Mutable-descriptor result-wrapper old-field roots exercise the
// conservative boundary where a value-producing old field and a
// mutable descriptor read must stay before a catchable call wrapper;
// the later same-field store remains rather than folding.
let descriptor_ref = ValType::ref_type(
RefType::new(true, HeapType::new(descriptor_idx), exact=true),
)
match
(
gen_matching_global_idx(
env.globals,
descriptor_ref,
mutable_only=true,
),
env.current_func_idx,
) {
(Some(desc_global_idx), Some(call_idx)) if !env.tags.is_empty() &&
!env.mems.is_empty() =>
match gen_valid_callable_by_idx(env.funcs, call_idx) {
Some(target) if target.params.is_empty() &&
target.results.is_empty() => {
out.push(Instruction::i32_const(I32(1)))
out.push(Instruction::memory_grow(MemIdx::new(0U)))
out.push(
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
)
out.push(Instruction::global_get(desc_global_idx))
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::call(call_idx),
Instruction::i32_const(I32(135)),
]),
),
Instruction::drop(),
]),
),
)
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(136)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
}
_ => ()
}
_ => ()
}
// Descriptor catch/throw skip-local-set hazards mirror the ordinary
// catchable root below while keeping descriptor materialization in
// the generated profile. The throw sibling can skip the constructor
// assignment, so HSO must not fold the later store into this
// descriptor-bearing constructor.
if !env.tags.is_empty() && !env.mems.is_empty() {
let tag_idx = TagIdx::new(0U)
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::memory_size(MemIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::throw_(tag_idx)],
Some([
Instruction::i32_const(I32(105)),
Instruction::ref_null(
HeapType::abs(AbsHeapType::eq()),
),
Instruction::struct_new_default(descriptor_idx),
Instruction::struct_new_desc(described_idx),
Instruction::local_set(described_local_idx),
]),
),
]),
),
]),
),
)
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(106)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
}
// Descriptor branch skip-local-set hazards cover the non-exceptional
// sibling of the catch/throw root: a branch inside the constructor
// wrapper can skip the local.set, so the later local.get/struct.set
// must not be assumed to use this fresh descriptor constructor.
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::i32_const(I32(107)),
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
Instruction::struct_new_default(descriptor_idx),
Instruction::struct_new_desc(described_idx),
Instruction::local_set(described_local_idx),
]),
),
)
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(108)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
// Exact descriptor branch-result roots cover the br_on_non_null
// descriptor operand surface that previously aborted Starshine's HOT
// verifier/lowerer before direct HSO could compare against Binaryen.
out.push(Instruction::i32_const(I32(127)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(
Instruction::block(
BlockType::val_type(
ValType::ref_type(
RefType::new(false, HeapType::new(descriptor_idx), exact=true),
),
),
Expr::new([
Instruction::ref_null_type(
RefType::new(true, HeapType::new(descriptor_idx), exact=true),
),
Instruction::br_on_non_null(LabelIdx::new(0U)),
Instruction::unreachable_(),
]),
),
)
out.push(Instruction::struct_new_desc(described_idx))
out.push(Instruction::local_set(described_local_idx))
out.push(Instruction::local_get(described_local_idx))
out.push(Instruction::i32_const(I32(128)))
out.push(Instruction::struct_set(described_idx, U32::new(0U)))
}
None => ()
}
}
_ => ()
}
// Void try_table/table.set roots exercise the wrapped trySwap path. The
// table root is deliberately non-throwing and does not touch the target
// local, so Binaryen folds the later same-local struct.set into the fresh
// constructor and preserves the table side effect before the new local.set.
if !env.mems.is_empty() && !env.tables.is_empty() {
let TableType(table_rt, _) = env.tables[0]
if ValType::ref_type(table_rt) == ValType::funcref() {
// Result-typed same-resource memory roots keep the generated HSO-G
// profile honest for wrappers that produce a value and also perform a
// memory.fill touching the constructor's memory-size resource.
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(9)),
Instruction::i32_const(I32(1)),
Instruction::memory_fill(MemIdx::new(0U)),
Instruction::i32_const(I32(114)),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(115)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Result-typed cross-family roots exercise the positive side of the
// trySwap matrix: a memory-size constructor can still fold across a
// result wrapper that performs an unrelated table.set before returning
// a dropped i32.
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::ref_null(HeapType::abs(AbsHeapType::func())),
Instruction::table_set(TableIdx::new(0U)),
Instruction::i32_const(I32(116)),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(117)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Catchable result-typed same-resource roots keep the generated profile
// honest for wrappers whose memory.fill touches the constructor's
// memory-size resource and whose body can branch to a local catch.
if !env.tags.is_empty() {
let tag_idx = TagIdx::new(0U)
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(8)),
Instruction::i32_const(I32(1)),
Instruction::memory_fill(MemIdx::new(0U)),
Instruction::memory_size(MemIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::throw_(tag_idx)],
Some([]),
),
Instruction::i32_const(I32(118)),
]),
),
Instruction::drop(),
]),
),
)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(119)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
// Catchable result-typed direct-call wrappers keep generated coverage on
// the broader call-bearing try_table surface. The call is intentionally
// void and catchable by the wrapper, and the later store remains after the
// wrapper so compare can classify Binaryen's conservative call barrier.
match env.current_func_idx {
Some(call_idx) if !env.tags.is_empty() =>
match gen_valid_callable_by_idx(env.funcs, call_idx) {
Some(target) if target.params.is_empty() &&
target.results.is_empty() => {
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::call(call_idx),
Instruction::i32_const(I32(129)),
]),
),
Instruction::drop(),
]),
),
)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(130)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
_ => ()
}
_ => ()
}
// Indirect-call wrappers cover the call_indirect sibling of the
// catchable result-typed call surface. The profile uses the current
// no-param/no-result function type and table slot zero so validation can
// exercise HSO's conservative indirect-call barrier without relying on
// the random body generator.
match env.current_func_idx {
Some(call_idx) if !env.tags.is_empty() =>
match gen_valid_callable_by_idx(env.funcs, call_idx) {
Some(target) if target.params.is_empty() &&
target.results.is_empty() => {
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::call_indirect(
target.type_idx,
TableIdx::new(0U),
),
Instruction::i32_const(I32(131)),
]),
),
Instruction::drop(),
]),
),
)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(132)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
_ => ()
}
_ => ()
}
// Typed-function-reference call wrappers cover the matching call_ref
// surface when the module has a declared ref.func target.
match env.declared_ref_func_idx {
Some(func_idx) if !env.tags.is_empty() =>
match gen_valid_callable_by_idx(env.funcs, func_idx) {
Some(target) if target.params.is_empty() &&
target.results.is_empty() => {
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::ref_func(target.idx),
Instruction::call_ref(target.type_idx),
Instruction::i32_const(I32(133)),
]),
),
Instruction::drop(),
]),
),
)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(134)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
_ => ()
}
_ => ()
}
// Table-side result-typed cross-family roots cover the counterpart where
// a table-size constructor can fold across an unrelated memory store.
out.push(Instruction::table_size(TableIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(120)),
Instruction::i32_store(gen_valid_memarg()),
Instruction::i32_const(I32(121)),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(122)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Result-typed cross-family growth roots cover HSO-G's growth positive
// split: memory.size may fold across table.grow, and table.size may
// fold across memory.grow, because the intervening growth touches the
// other resource family even when wrapped in a result-typed try_table.
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::func())),
Instruction::i32_const(I32(1)),
Instruction::table_grow(TableIdx::new(0U)),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(123)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::table_size(TableIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::memory_grow(MemIdx::new(0U)),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(124)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Table-side result-typed same-resource roots exercise the no-fold
// side of the result-wrapper matrix: a table.size constructor must not
// move across a wrapped table.fill touching the same table resource.
out.push(Instruction::table_size(TableIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::ref_null(HeapType::abs(AbsHeapType::func())),
Instruction::i32_const(I32(1)),
Instruction::table_fill(TableIdx::new(0U)),
Instruction::i32_const(I32(125)),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(126)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::ref_null(HeapType::abs(AbsHeapType::func())),
Instruction::table_set(TableIdx::new(0U)),
]),
),
]),
),
)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(100)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Same-resource memory roots are the complementary trySwap barrier:
// the constructor reads memory size, so a wrapped memory.fill must keep
// the later struct.set instead of letting HSO reorder across the fill.
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(1)),
Instruction::memory_fill(MemIdx::new(0U)),
]),
),
]),
),
)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(101)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
// Contained control flow in the wrapped table-side root should stay in
// the generated profile too: Binaryen can still fold the later store
// when the branch does not escape the root wrapper or touch the target.
out.push(Instruction::memory_size(MemIdx::new(0U)))
out.push(Instruction::ref_null(HeapType::abs(AbsHeapType::eq())))
out.push(Instruction::struct_new(struct_idx))
out.push(Instruction::local_set(local_idx))
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::ref_null(HeapType::abs(AbsHeapType::func())),
Instruction::table_set(TableIdx::new(0U)),
]),
),
]),
),
]),
),
)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(102)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
}
// Catchable control roots cover the LazyLocalGraph-style skip-local-set
// hazard: the local.set that records the fresh constructor is inside a
// try_table body with a catchable throw on a sibling path, so Binaryen must
// not treat the later local.get/struct.set as unconditionally tied to that
// constructor.
if !env.tags.is_empty() && !env.mems.is_empty() {
let tag_idx = TagIdx::new(0U)
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::all(LabelIdx::new(0U))],
Expr::new([
Instruction::memory_size(MemIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::throw_(tag_idx)],
Some([
Instruction::i32_const(I32(103)),
Instruction::ref_null(HeapType::abs(AbsHeapType::eq())),
Instruction::struct_new(struct_idx),
Instruction::local_set(local_idx),
]),
),
]),
),
]),
),
)
out.push(Instruction::local_get(local_idx))
out.push(Instruction::i32_const(I32(104)))
out.push(Instruction::struct_set(struct_idx, U32::new(0U)))
}
}
///|
fn gen_valid_build_func(
ctx : GenValidContext,
accepts : Array[ValType],
returns : Array[ValType],
globals : Array[GlobalType],
tables : Array[TableType],
mems : Array[MemType],
tags : Array[TagType],
funcs : Array[GenValidFuncSig],
data_idxs : Array[DataIdx],
_elem_idxs : Array[ElemIdx],
passive_elem_idxs : Array[ElemIdx],
passive_elem_ref_types : Array[RefType],
bulk_elem_seed_idx : ElemIdx?,
gc_type_plan : GenValidGcTypePlan,
declared_ref_func_idx : FuncIdx?,
current_func_idx~ : FuncIdx? = None,
) -> Func {
let local_ref_types = gc_type_plan.concrete_ref_types.copy()
for vt in gc_type_plan.exact_ref_types {
local_ref_types.push(vt)
}
let locals = gen_local_types(ctx, extra_ref_types=local_ref_types)
if ctx.config.mode == CoverageForced {
let mut has_i32_local = false
for vt in accepts {
if vt == ValType::i32() {
has_i32_local = true
}
}
for vt in locals {
if vt == ValType::i32() {
has_i32_local = true
}
}
if !has_i32_local {
locals.push(ValType::i32())
}
if ctx.config.features.allow_typed_body_generator &&
gen_matching_local_idx(
gen_all_local_types(accepts, locals),
ValType::i64(),
)
is None {
locals.push(ValType::i64())
}
if ctx.config.features.allow_typed_body_generator &&
ctx.config.features.allow_v128 &&
gen_matching_local_idx(
gen_all_local_types(accepts, locals),
ValType::v128(),
)
is None {
locals.push(ValType::v128())
}
if ctx.config.features.allow_ref_types &&
!ctx.config.features.allow_heap_store_optimization_body_generator {
match declared_ref_func_idx {
Some(func_idx) =>
match gen_valid_callable_by_idx(funcs, func_idx) {
Some(target) => {
let fref = ValType::ref_type(
RefType::new(true, HeapType::new(target.type_idx)),
)
if gen_matching_local_idx(
gen_all_local_types(accepts, locals),
fref,
)
is None {
locals.push(fref)
}
}
None => ()
}
None => ()
}
}
if ctx.config.features.allow_ref_types &&
!tags.is_empty() &&
gen_matching_local_idx(
gen_all_local_types(accepts, locals),
ValType::ref_null_exn(),
)
is None {
locals.push(ValType::ref_null_exn())
}
}
gen_valid_ensure_body_layout_locals(ctx, locals)
if ctx.config.mode == Natural {
for vt in returns {
match vt {
RefTypeValType(rt) if rt.is_exact() => {
let has_existing_exact_route = gen_matching_local_idx(
gen_all_local_types(accepts, locals),
vt,
)
is Some(_) ||
gen_matching_global_idx(globals, vt) is Some(_) ||
(
ctx.config.features.allow_calls &&
gen_valid_has_callable_with_result(funcs, vt)
) ||
(
ctx.config.features.allow_ref_types &&
gen_valid_declared_ref_callable_with_result(
funcs, declared_ref_func_idx, vt,
)
is Some(_)
)
if !has_existing_exact_route {
locals.push(vt)
}
}
_ => ()
}
}
}
if ctx.config.mode == CoverageForced {
if ctx.config.features.allow_heap_store_optimization_body_generator {
if !gc_type_plan.struct_type_idxs.is_empty() {
let struct_ref = ValType::ref_type(
RefType::new(true, HeapType::new(gc_type_plan.struct_type_idxs[0])),
)
if gen_matching_local_idx(
gen_all_local_types(accepts, locals),
struct_ref,
)
is None {
locals.push(struct_ref)
}
}
match gc_type_plan.descriptor_struct_idx {
Some(described_idx) => {
let described_ref = ValType::ref_type(
RefType::new(true, HeapType::new(described_idx), exact=true),
)
if gen_matching_local_idx(
gen_all_local_types(accepts, locals),
described_ref,
)
is None {
locals.push(described_ref)
}
}
None => ()
}
} else if ctx.config.features.allow_heap2local_body_generator {
if !gc_type_plan.struct_type_idxs.is_empty() {
let struct_ref = ValType::ref_type(
RefType::new(true, HeapType::new(gc_type_plan.struct_type_idxs[0])),
)
if gen_matching_local_idx(
gen_all_local_types(accepts, locals),
struct_ref,
)
is None {
locals.push(struct_ref)
}
}
if !gc_type_plan.array_type_idxs.is_empty() {
let array_ref = ValType::ref_type(
RefType::new(true, HeapType::new(gc_type_plan.array_type_idxs[0])),
)
if gen_matching_local_idx(
gen_all_local_types(accepts, locals),
array_ref,
)
is None {
locals.push(array_ref)
}
}
} else if gen_valid_is_local_subtyping_family_config(ctx.config) ||
gen_valid_is_optimize_casts_family_config(ctx.config) {
let local_count = if ctx.config ==
GenValidConfig::for_profile(LocalSubtypingIterationProfile) {
3
} else {
1
}
for _ in 0.. ()
// SSA templates are a no-op unless allow_ssa_nomerge_body_generator (see gen_valid_ssa.mbt).
_ => gen_valid_append_ssa_nomerge_body_slice(body_instrs, ctx, env, accepts)
}
if ctx.config.mode == Natural && ctx.config.features.allow_ref_types {
let gc_stmt_count = if gc_type_plan.concrete_ref_types.is_empty() {
1 + ctx.random_int_from(BodyStream, 2)
} else {
2 + ctx.random_int_from(BodyStream, 2)
}
for _ in 0.. Func {
gen_valid_build_func(
ctx,
accepts,
returns,
[],
[],
[],
[],
[],
[],
[],
[],
[],
None,
gen_valid_gc_type_plan_empty(),
None,
)
}
///|
fn gen_valid_choose_optional_count_with_coverage_floor_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
allow : Bool,
max_count : Int32,
percent : Int32,
coverage_floor : Int32,
) -> Int32 {
let bounded_max = gen_valid_clamp_non_negative(max_count)
if !allow || bounded_max <= 0 {
0
} else if ctx.config.mode == CoverageForced {
let floor = gen_valid_min_int(
bounded_max,
gen_valid_clamp_non_negative(coverage_floor),
)
floor + ctx.random_int_from(label, bounded_max - floor + 1)
} else if gen_valid_roll_percent_from(ctx, label, percent) {
1 + ctx.random_int_from(label, bounded_max)
} else {
0
}
}
///|
fn gen_valid_choose_optional_count_with_coverage_floor(
ctx : GenValidContext,
allow : Bool,
max_count : Int32,
percent : Int32,
coverage_floor : Int32,
) -> Int32 {
gen_valid_choose_optional_count_with_coverage_floor_from(
ctx,
ModuleTopologyStream,
allow,
max_count,
percent,
coverage_floor,
)
}
///|
fn gen_valid_choose_optional_count_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
allow : Bool,
max_count : Int32,
percent : Int32,
) -> Int32 {
gen_valid_choose_optional_count_with_coverage_floor_from(
ctx, label, allow, max_count, percent, 1,
)
}
///|
fn gen_valid_choose_defined_func_count(ctx : GenValidContext) -> Int32 {
let bounded_max = gen_valid_clamp_non_negative(ctx.config.max_defined_funcs)
if bounded_max <= 1 {
1
} else if gen_valid_is_topology_heavy_config(ctx.config) {
let floor = gen_valid_min_int(10, bounded_max)
floor + ctx.random_int_from(FuncStream, bounded_max - floor + 1)
} else if gen_valid_is_control_heavy_config(ctx.config) && bounded_max > 3 {
4 + ctx.random_int_from(FuncStream, bounded_max - 3)
} else if ctx.config.mode == CoverageForced {
2 + ctx.random_int_from(FuncStream, bounded_max - 1)
} else {
1 + ctx.random_int_from(FuncStream, bounded_max)
}
}
///|
fn gen_valid_active_i32_offset_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
global_idx~ : GlobalIdx? = None,
) -> Expr {
if ctx.config.features.allow_const_expr_variants &&
(ctx.config.mode == CoverageForced || ctx.random_int_from(label, 4) == 0) {
match global_idx {
Some(idx) => return Expr::new([Instruction::global_get(idx)])
None => ()
}
}
Expr::new([Instruction::i32_const(I32(ctx.random_int_from(label, 4)))])
}
///|
fn gen_valid_active_i32_boundary_offset() -> Expr {
Expr::new([Instruction::i32_const(I32(65536))])
}
///|
fn gen_valid_active_i64_boundary_offset() -> Expr {
Expr::new([Instruction::i64_const(I64(4294967296L))])
}
///|
fn gen_valid_active_offset_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
addr_type : ValType,
global_idx~ : GlobalIdx? = None,
) -> Expr {
if addr_type == ValType::i32() {
gen_valid_active_i32_offset_from(ctx, label, global_idx~)
} else if addr_type == ValType::i64() {
if ctx.config.features.allow_const_expr_variants &&
(ctx.config.mode == CoverageForced || ctx.random_int_from(label, 4) == 0) {
match global_idx {
Some(idx) => return Expr::new([Instruction::global_get(idx)])
None => ()
}
}
Expr::new([
Instruction::i64_const(I64(ctx.random_int_from(label, 4).to_int64())),
])
} else {
gen_valid_const_expr_from_context(
ctx,
label,
addr_type,
gen_valid_const_expr_context_for_use(DataOffsetConstExpr),
[],
None,
)
}
}
///|
fn gen_valid_active_i32_offset(
ctx : GenValidContext,
global_idx~ : GlobalIdx? = None,
) -> Expr {
gen_valid_active_i32_offset_from(ctx, ModuleTopologyStream, global_idx~)
}
///|
fn gen_valid_memory_limits_i32(
min : UInt32,
max : UInt32?,
shared : Bool,
) -> MemType {
MemType::new(Limits::i32(min, max), shared~)
}
///|
fn gen_valid_memory_limits_i64(
min : UInt64,
max : UInt64?,
shared : Bool,
) -> MemType {
MemType::new(Limits::i64(min, max), shared~)
}
///|
fn gen_valid_mem_type(ctx : GenValidContext, total_mem_idx : Int32) -> MemType {
let variants = ctx.config.features.allow_memory_limit_variants
let shared_enabled = ctx.config.features.allow_shared_memories
let memory64_enabled = ctx.config.features.allow_memory64
if total_mem_idx == 0 &&
ctx.config.features.allow_heap_store_optimization_body_generator &&
ctx.config.max_body_statements == 97 {
gen_valid_memory_limits_i32(1U, Some(1U), true)
} else if total_mem_idx == 0 {
if variants && ctx.config.mode == CoverageForced {
gen_valid_memory_limits_i32(0U, None, false)
} else {
let min = if variants && ctx.random_int_from(MemoryStream, 5) == 0 {
0U
} else {
1U
}
let max = if variants && ctx.random_int_from(MemoryStream, 4) == 0 {
None
} else {
Some(
min + 1U + ctx.random_int_from(MemoryStream, 4).reinterpret_as_uint(),
)
}
gen_valid_memory_limits_i32(min, max, false)
}
} else if shared_enabled &&
ctx.config.mode == CoverageForced &&
total_mem_idx == 1 {
gen_valid_memory_limits_i32(1U, Some(2U), true)
} else if memory64_enabled &&
ctx.config.mode == CoverageForced &&
total_mem_idx == 2 {
gen_valid_memory_limits_i64(1UL, Some(2UL), false)
} else if shared_enabled && ctx.random_int_from(MemoryStream, 6) == 0 {
let min = if variants && ctx.random_int_from(MemoryStream, 3) == 0 {
0U
} else {
1U
}
let max = Some(
min + 1U + ctx.random_int_from(MemoryStream, 4).reinterpret_as_uint(),
)
gen_valid_memory_limits_i32(min, max, true)
} else if memory64_enabled && ctx.random_int_from(MemoryStream, 5) == 0 {
let min = if variants && ctx.random_int_from(MemoryStream, 3) == 0 {
0UL
} else {
1UL
}
let max = if variants && ctx.random_int_from(MemoryStream, 4) == 0 {
None
} else {
Some(min + 1UL + ctx.random_int_from(MemoryStream, 4).to_uint64())
}
gen_valid_memory_limits_i64(min, max, false)
} else {
let min = if variants && ctx.random_int_from(MemoryStream, 5) == 0 {
0U
} else {
1U
}
let max = if variants && ctx.random_int_from(MemoryStream, 4) == 0 {
None
} else {
Some(
min + 1U + ctx.random_int_from(MemoryStream, 4).reinterpret_as_uint(),
)
}
gen_valid_memory_limits_i32(min, max, false)
}
}
///|
fn gen_valid_table_limits_i32(
ctx : GenValidContext,
total_table_idx : Int32,
) -> Limits {
if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 1 {
Limits::i32(0U, Some(3U))
} else if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 2 {
Limits::i32(1U, None)
} else {
let min = if ctx.config.features.allow_table_limit_variants &&
ctx.random_int_from(TableStream, 5) == 0 {
0U
} else {
1U
}
let max = if ctx.config.features.allow_table_limit_variants &&
ctx.random_int_from(TableStream, 4) == 0 {
None
} else {
Some(min + 1U + ctx.random_int_from(TableStream, 4).reinterpret_as_uint())
}
Limits::i32(min, max)
}
}
///|
fn gen_valid_table_ref_type(
ctx : GenValidContext,
total_table_idx : Int32,
gc_type_plan : GenValidGcTypePlan,
) -> RefType {
if total_table_idx == 0 ||
!ctx.config.features.allow_ref_types ||
!ctx.config.features.allow_table_limit_variants {
RefType::new(true, HeapType::abs(AbsHeapType::func()))
} else if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 1 {
RefType::new(true, HeapType::abs(AbsHeapType::extern_()))
} else if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 2 {
RefType::new(true, HeapType::new(TypeIdx::new(0U)))
} else if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 3 {
RefType::new(true, HeapType::abs(AbsHeapType::i31()))
} else if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 4 {
RefType::new(true, HeapType::abs(AbsHeapType::func()))
} else if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 5 {
match gen_valid_first_array_const_expr_shape(gc_type_plan) {
Some(shape) => gen_valid_array_ref_type_from_shape(shape)
None => RefType::new(true, HeapType::abs(AbsHeapType::func()))
}
} else if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 6 {
match gen_valid_v128_array_const_expr_shape(gc_type_plan) {
Some(shape) => gen_valid_array_ref_type_from_shape(shape)
None => RefType::new(true, HeapType::abs(AbsHeapType::func()))
}
} else if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx > 6 {
RefType::new(true, HeapType::abs(AbsHeapType::func()))
} else if ctx.config.features.allow_table_limit_variants &&
ctx.random_int_from(TableStream, 6) == 0 {
RefType::new(true, HeapType::abs(AbsHeapType::extern_()))
} else if !gc_type_plan.concrete_ref_types.is_empty() &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TableStream, 3) == 0
) {
match
gc_type_plan.concrete_ref_types[ctx.random_int_from(
TableStream,
gc_type_plan.concrete_ref_types.length(),
)] {
RefTypeValType(rt) => rt
_ => RefType::new(true, HeapType::abs(AbsHeapType::eq()))
}
} else {
RefType::new(true, HeapType::abs(AbsHeapType::eq()))
}
}
///|
fn gen_valid_table_type(
ctx : GenValidContext,
total_table_idx : Int32,
gc_type_plan : GenValidGcTypePlan,
) -> TableType {
TableType::new(
gen_valid_table_ref_type(ctx, total_table_idx, gc_type_plan),
gen_valid_table_limits_i32(ctx, total_table_idx),
)
}
///|
fn gen_valid_table_init_expr(
ctx : GenValidContext,
total_table_idx : Int32,
rt : RefType,
func_idx : FuncIdx,
imported_global_types : Array[GlobalType],
gc_type_plan : GenValidGcTypePlan,
) -> Expr? {
if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 5 {
match gen_valid_array_const_expr_shape_for_ref_type(gc_type_plan, rt) {
Some(shape) =>
return Some(
gen_valid_array_const_expr_from_shape(
ctx,
TableStream,
shape,
ArrayNewFixedConstExpr,
),
)
None => ()
}
}
if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
total_table_idx == 6 {
match gen_valid_v128_array_const_expr_shape(gc_type_plan) {
Some(shape) =>
return Some(
gen_valid_array_const_expr_from_shape(
ctx,
TableStream,
shape,
ArrayNewFixedConstExpr,
),
)
None => ()
}
}
if ctx.config.features.allow_const_expr_variants &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(TableStream, 4) == 0
) {
match
gen_matching_immutable_global_idx(
imported_global_types,
ValType::ref_type(rt),
) {
Some(idx) => return Some(Expr::new([Instruction::global_get(idx)]))
None => ()
}
}
if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode != CoverageForced &&
ctx.random_int_from(TableStream, 4) == 0 {
match gen_valid_array_const_expr_shape_for_ref_type(gc_type_plan, rt) {
Some(shape) =>
return Some(
gen_valid_array_const_expr_from_shape(
ctx,
TableStream,
shape,
ArrayNewFixedConstExpr,
),
)
None => ()
}
}
if ctx.config.features.allow_table_limit_variants &&
ctx.config.mode == CoverageForced {
Some(gen_valid_elem_ref_expr(ctx, rt, func_idx~, gc_type_plan~))
} else if ctx.config.features.allow_table_limit_variants &&
ctx.random_int_from(TableStream, 5) == 0 {
Some(gen_valid_elem_ref_expr(ctx, rt, func_idx~, gc_type_plan~))
} else {
None
}
}
///|
fn gen_valid_rec_type_flat_count(rec_type : RecType) -> Int32 {
match rec_type {
SingleRecType(_) => 1
GroupRecType(group) => group.length()
}
}
///|
fn gen_valid_rec_types_flat_count(rec_types : Array[RecType]) -> Int32 {
let mut count = 0
for rec_type in rec_types {
count += gen_valid_rec_type_flat_count(rec_type)
}
count
}
///|
fn gen_valid_pick_type_idx_from(
ctx : GenValidContext,
label : GenValidRandomStreamLabel,
type_count : Int32,
) -> TypeIdx {
TypeIdx::new(ctx.random_int_from(label, type_count).reinterpret_as_uint())
}
///|
fn gen_valid_pick_func_type_idx(
ctx : GenValidContext,
type_count : Int32,
) -> TypeIdx {
gen_valid_pick_type_idx_from(ctx, FuncStream, type_count)
}
///|
fn gen_valid_name(ctx : GenValidContext, base : StringView) -> Name {
let limit = ctx.config.max_name_length
if limit <= 0 {
return Name::new("")
}
if base.length() <= limit {
return Name::new(base)
}
let out = StringBuilder::new()
for i = 0; i < limit; i = i + 1 {
out.write_char('n')
}
Name::from_string(out.to_string())
}
///|
fn gen_valid_payload(ctx : GenValidContext, payload : Bytes) -> Bytes {
let limit = ctx.config.max_segment_payload_size
if limit < 0 {
Bytes::new(0)
} else if payload.length() <= limit {
payload
} else {
Bytes::new(limit)
}
}
///|
fn gen_valid_import_module_name(ctx : GenValidContext, index : Int32) -> Name {
if gen_valid_is_topology_heavy_config(ctx.config) {
match index % 6 {
0 => gen_valid_name(ctx, "env")
1 => gen_valid_name(ctx, "")
2 => gen_valid_name(ctx, "fzg.topology.a")
3 =>
gen_valid_name(
ctx, "fzg.import.module.with.a.deliberately.long.edge.profile",
)
4 => gen_valid_name(ctx, "fzg.模块.🧪")
_ => gen_valid_name(ctx, "env")
}
} else {
gen_valid_name(ctx, "env")
}
}
///|
fn gen_valid_gsi_desc_cast_ref_type(
type_idx : TypeIdx,
nullable : Bool,
) -> ValType {
ValType::ref_type(RefType::new(nullable, HeapType::new(type_idx)))
}
///|
fn gen_valid_gsi_desc_cast_exact_ref_type(
type_idx : TypeIdx,
nullable : Bool,
) -> ValType {
ValType::ref_type(RefType::new(nullable, HeapType::new(type_idx), exact=true))
}
///|
fn gen_valid_gsi_desc_cast_global(desc_type : TypeIdx) -> Global {
Global::new(
GlobalType::new(
gen_valid_gsi_desc_cast_exact_ref_type(desc_type, false),
false,
),
Expr::new([Instruction::struct_new(desc_type)]),
)
}
///|
fn gen_valid_gsi_desc_cast_types(
include_strict_subtype : Bool,
) -> Array[RecType] {
let type_a = TypeIdx::new(0U)
let type_a_desc = TypeIdx::new(1U)
let types : Array[RecType] = [
RecType::group([
SubType::new(
false,
[],
CompType::struct_([]),
metadata=TypeMetadata::new(descriptor=Some(type_a_desc)),
),
SubType::new(
false,
[],
CompType::struct_([]),
metadata=TypeMetadata::new(describes=Some(type_a)),
),
]),
]
if include_strict_subtype {
let type_b = TypeIdx::new(2U)
let type_b_desc = TypeIdx::new(3U)
types.push(
RecType::group([
SubType::new(
false,
[type_a],
CompType::struct_([]),
metadata=TypeMetadata::new(descriptor=Some(type_b_desc)),
),
SubType::new(
false,
[type_a_desc],
CompType::struct_([]),
metadata=TypeMetadata::new(describes=Some(type_b)),
),
]),
)
}
types
}
///|
fn gen_valid_gsi_desc_cast_positive_body() -> Array[Instruction] {
let type_a = TypeIdx::new(0U)
let nullable_box = gen_valid_gsi_desc_cast_ref_type(type_a, true)
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_cast(true, HeapType::new(type_a)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_cast_type(
RefType::new(false, HeapType::new(type_a), exact=true),
),
Instruction::drop(),
Instruction::block(
BlockType::val_type(nullable_box),
Expr::new([Instruction::local_get(LocalIdx::new(0U))]),
),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::select(types=Some([nullable_box])),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::if_(
BlockType::val_type(nullable_box),
[Instruction::local_get(LocalIdx::new(0U))],
Some([Instruction::local_get(LocalIdx::new(1U))]),
),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
Instruction::loop_(
BlockType::val_type(nullable_box),
Expr::new([Instruction::local_get(LocalIdx::new(0U))]),
),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::nop(),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
]
}
///|
fn gen_valid_gsi_desc_cast_boundary_body(
hard_unreachable : Bool,
) -> Array[Instruction] {
let type_a = TypeIdx::new(0U)
if hard_unreachable {
[
Instruction::unreachable_(),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
]
} else {
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
]
}
}
///|
fn gen_valid_gsi_desc_cast_strict_body() -> Array[Instruction] {
let type_a = TypeIdx::new(0U)
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_cast(false, HeapType::new(type_a)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_cast_type(
RefType::new(false, HeapType::new(type_a), exact=true),
),
Instruction::drop(),
]
}
///|
fn gen_valid_gsi_desc_cast_profile_module(config : GenValidConfig) -> Module {
let include_strict = config ==
GenValidConfig::for_profile(GsiDescCastStrictSubtypeProfile)
let hard_unreachable = config ==
GenValidConfig::for_profile(GsiDescCastUnreachableBoundaryProfile)
let positive = config ==
GenValidConfig::for_profile(GsiDescCastPositiveProfile)
let type_a = TypeIdx::new(0U)
let type_a_desc = TypeIdx::new(1U)
let func_type_idx = TypeIdx::new(
(if include_strict { 4 } else { 2 }).reinterpret_as_uint(),
)
let params = if hard_unreachable {
[]
} else if include_strict {
[ValType::anyref()]
} else if positive {
[
gen_valid_gsi_desc_cast_ref_type(type_a, true),
gen_valid_gsi_desc_cast_ref_type(type_a, true),
ValType::i32(),
]
} else {
[gen_valid_gsi_desc_cast_ref_type(type_a, true)]
}
let body = if hard_unreachable {
gen_valid_gsi_desc_cast_boundary_body(true)
} else if include_strict {
gen_valid_gsi_desc_cast_strict_body()
} else if positive {
gen_valid_gsi_desc_cast_positive_body()
} else {
gen_valid_gsi_desc_cast_boundary_body(false)
}
let globals : Array[Global] = []
let mut global_idx = 0
while global_idx < config.max_globals {
globals.push(gen_valid_gsi_desc_cast_global(type_a_desc))
global_idx += 1
}
let types = gen_valid_gsi_desc_cast_types(include_strict)
types.push(RecType::new(SubType::comp_type(CompType::func(params, []))))
let mod = Module::new()
.with_type_sec(TypeSec::new(types))
.with_func_sec(FuncSec::new([func_type_idx]))
.with_code_sec(CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]))
if globals.is_empty() {
mod
} else {
mod.with_global_sec(GlobalSec::new(globals))
}
}
///|
fn gen_valid_precompute_void_func_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [])))
}
///|
fn gen_valid_precompute_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(PrecomputeScalarValueProfile) {
PrecomputeScalarValueProfile
} else if config == GenValidConfig::for_profile(PrecomputeGcValueProfile) {
PrecomputeGcValueProfile
} else if config ==
GenValidConfig::for_profile(PrecomputeEffectfulValueProfile) {
PrecomputeEffectfulValueProfile
} else if config == GenValidConfig::for_profile(PrecomputeControlProfile) {
PrecomputeControlProfile
} else if config == GenValidConfig::for_profile(PrecomputeGlobalProfile) {
PrecomputeGlobalProfile
} else if config == GenValidConfig::for_profile(PrecomputeDropCleanupProfile) {
PrecomputeDropCleanupProfile
} else if config ==
GenValidConfig::for_profile(PrecomputeEffectBoundaryProfile) {
PrecomputeEffectBoundaryProfile
} else if config ==
GenValidConfig::for_profile(PrecomputeGcAtomicBoundaryProfile) {
PrecomputeGcAtomicBoundaryProfile
} else if config ==
GenValidConfig::for_profile(PrecomputeDirectPrefixWatchProfile) {
PrecomputeDirectPrefixWatchProfile
} else if config ==
GenValidConfig::for_profile(PrecomputePropagateLocalFactsProfile) {
PrecomputePropagateLocalFactsProfile
} else {
PrecomputeScalarProfile
}
}
///|
fn gen_valid_precompute_record_i32(global_idx : UInt32) -> Array[Instruction] {
[
Instruction::global_get(GlobalIdx::new(global_idx)),
Instruction::i32_add(),
Instruction::global_set(GlobalIdx::new(global_idx)),
]
}
///|
fn gen_valid_precompute_scalar_body() -> Array[Instruction] {
let body : Array[Instruction] = [
Instruction::i32_const(I32(4)),
Instruction::i32_const(I32(5)),
Instruction::i32_add(),
]
body.append(gen_valid_precompute_record_i32(0U))
body.append([
Instruction::i64_const(I64(6L)),
Instruction::i64_const(I64(7L)),
Instruction::i64_mul(),
Instruction::i32_wrap_i64(),
])
body.append(gen_valid_precompute_record_i32(0U))
body.append([Instruction::i32_const(I32(0)), Instruction::i32_eqz()])
body.append(gen_valid_precompute_record_i32(0U))
body.append([
Instruction::i64_const(I64(9L)),
Instruction::i64_const(I64(3L)),
Instruction::i64_gt_u(),
])
body.append(gen_valid_precompute_record_i32(0U))
body.append([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(4)),
Instruction::i32_shl(),
])
body.append(gen_valid_precompute_record_i32(0U))
body
}
///|
fn gen_valid_precompute_control_body() -> Array[Instruction] {
let yes = [Instruction::i32_const(I32(9))]
yes.append(gen_valid_precompute_record_i32(0U))
let no = [Instruction::i32_const(I32(10))]
no.append(gen_valid_precompute_record_i32(0U))
let body : Array[Instruction] = [
Instruction::i32_const(I32(1)),
Instruction::if_(BlockType::void_(), yes, Some(no)),
Instruction::i32_const(I32(0)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(2))],
Some([Instruction::i32_const(I32(3))]),
),
]
body.append(gen_valid_precompute_record_i32(0U))
body.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::i32_const(I32(11))]),
),
)
body.append(gen_valid_precompute_record_i32(0U))
body
}
///|
fn gen_valid_precompute_control_module() -> Module {
let void_type = RecType::new(SubType::comp_type(CompType::func([], [])))
let pair_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32(), ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([void_type, pair_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new(gen_valid_precompute_control_body())),
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i64_const(I64(2L)),
Instruction::br(LabelIdx::new(1U)),
]),
),
Instruction::unreachable_(),
]),
),
]),
),
]),
)
}
///|
fn gen_valid_precompute_global_body() -> Array[Instruction] {
let body : Array[Instruction] = [
Instruction::i32_const(I32(8)),
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::i32_add(),
]
body.append(gen_valid_precompute_record_i32(3U))
body.append([
Instruction::global_get(GlobalIdx::new(1U)),
Instruction::i64_eqz(),
])
body.append(gen_valid_precompute_record_i32(3U))
body.append([
Instruction::global_get(GlobalIdx::new(2U)),
Instruction::ref_is_null(),
])
body.append(gen_valid_precompute_record_i32(3U))
body
}
///|
fn gen_valid_precompute_drop_cleanup_body() -> Array[Instruction] {
let body : Array[Instruction] = [Instruction::i32_const(I32(1))]
body.append(gen_valid_precompute_record_i32(0U))
body.append([
Instruction::i32_const(I32(2)),
Instruction::i32_const(I32(3)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
])
body.append(gen_valid_precompute_record_i32(0U))
body.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::i32_const(I32(6))]),
),
)
body.append(gen_valid_precompute_record_i32(0U))
body
}
///|
fn gen_valid_precompute_effect_boundary_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(8)),
Instruction::i32_const(I32(2)),
Instruction::i32_div_s(),
Instruction::drop(),
Instruction::i32_const(I32(11)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_load(MemArg::new(0U, None, 0UL)),
Instruction::drop(),
Instruction::call(FuncIdx::new(0U)),
Instruction::drop(),
]
}
///|
fn gen_valid_precompute_direct_prefix_watch_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(5)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
]
}
///|
fn gen_valid_precompute_propagate_local_facts_body() -> Array[Instruction] {
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(10)),
Instruction::local_set(LocalIdx::new(1U)),
],
Some([
Instruction::i32_const(I32(10)),
Instruction::local_set(LocalIdx::new(1U)),
]),
),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::call(FuncIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(10)),
Instruction::local_set(LocalIdx::new(2U)),
],
Some([
Instruction::i32_const(I32(20)),
Instruction::local_set(LocalIdx::new(2U)),
]),
),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::call(FuncIdx::new(0U)),
Instruction::local_get(LocalIdx::new(3U)),
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::local_tee(LocalIdx::new(4U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(4U)),
Instruction::call(FuncIdx::new(0U)),
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_tee(LocalIdx::new(5U)),
Instruction::drop(),
Instruction::i32_const(I32(0)),
]),
),
Instruction::local_set(LocalIdx::new(6U)),
Instruction::local_get(LocalIdx::new(5U)),
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(10)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(1)),
Instruction::i32_add(),
Instruction::local_set(LocalIdx::new(2U)),
],
Some([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(1)),
Instruction::i32_add(),
Instruction::local_set(LocalIdx::new(2U)),
]),
),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::i32_const(I32(10)),
Instruction::i32_add(),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::call(FuncIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(0U)),
]
}
///|
fn gen_valid_precompute_scalar_value_module() -> Module {
let i32_result = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let f64_result = RecType::new(
SubType::comp_type(CompType::func([], [ValType::f64()])),
)
let f32_result = RecType::new(
SubType::comp_type(CompType::func([], [ValType::f32()])),
)
let i64_result = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([i32_result, f64_result, f32_result, i64_result]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(2U),
TypeIdx::new(3U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(3U),
TypeIdx::new(3U),
TypeIdx::new(1U),
TypeIdx::new(0U),
TypeIdx::new(3U),
TypeIdx::new(3U),
TypeIdx::new(3U),
TypeIdx::new(2U),
TypeIdx::new(3U),
TypeIdx::new(3U),
TypeIdx::new(0U),
TypeIdx::new(3U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(3U),
TypeIdx::new(3U),
TypeIdx::new(0U),
TypeIdx::new(3U),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(8)), Instruction::i32_clz()]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(3)),
Instruction::i32_rotl(),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::f64_const(F64(9.0)), Instruction::f64_sqrt()]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f32_const(F32(Float::from_double(1.5))),
Instruction::f32_const(F32(Float::from_double(2.5))),
Instruction::f32_min(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(-1)),
Instruction::i64_extend_i32u(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f32_const(F32(Float::reinterpret_from_uint(0x7fc12345U))),
Instruction::f32_ceil(),
Instruction::i32_reinterpret_f32(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f32_const(F32(Float::reinterpret_from_uint(0x80000001U))),
Instruction::f32_nearest(),
Instruction::i32_reinterpret_f32(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f32_const(F32(Float::from_double(-1.0))),
Instruction::f32_sqrt(),
Instruction::i32_reinterpret_f32(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(F64(2.5)),
Instruction::f64_nearest(),
Instruction::i64_reinterpret_f64(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(F64(0.0)),
Instruction::f64_const(
F64(0x8000000000000000UL.reinterpret_as_double()),
),
Instruction::f64_max(),
Instruction::i64_reinterpret_f64(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(F64(4.0)),
Instruction::f64_const(F64(-1.0)),
Instruction::f64_copysign(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(F64(1.0e40)),
Instruction::i32_trunc_sat_f64s(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(F64(42.75)),
Instruction::i64_trunc_f64s(),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::i64_const(I64(8L)), Instruction::i64_ctz()]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i64_const(I64(1L)),
Instruction::i64_const(I64(63L)),
Instruction::i64_rotr(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i64_const(I64(0x3f800000L)),
Instruction::i32_wrap_i64(),
Instruction::f32_reinterpret_i32(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(F64(9223372036854775808.0)),
Instruction::i64_trunc_f64u(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(F64(18446744073709549568.0)),
Instruction::i64_trunc_f64u(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(
F64(0x7ff123456789abcdUL.reinterpret_as_double()),
),
Instruction::f32_demote_f64(),
Instruction::i32_reinterpret_f32(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f32_const(F32(Float::reinterpret_from_uint(0x7fc12345U))),
Instruction::f64_promote_f32(),
Instruction::i64_reinterpret_f64(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f32_const(F32(Float::reinterpret_from_uint(0x7fc12345U))),
Instruction::f32_const(F32(Float::from_double(1.0))),
Instruction::f32_add(),
Instruction::i32_reinterpret_f32(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f32_const(F32(Float::from_double(0.0))),
Instruction::f32_const(F32(Float::from_double(0.0))),
Instruction::f32_div(),
Instruction::i32_reinterpret_f32(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(
F64(0x7ff123456789abcdUL.reinterpret_as_double()),
),
Instruction::f64_const(F64(1.0)),
Instruction::f64_add(),
Instruction::i64_reinterpret_f64(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(F64(0.0)),
Instruction::f64_const(F64(0.0)),
Instruction::f64_div(),
Instruction::i64_reinterpret_f64(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f32_const(F32(Float::reinterpret_from_uint(0x80000000U))),
Instruction::f32_const(F32(Float::reinterpret_from_uint(0U))),
Instruction::f32_max(),
Instruction::i32_reinterpret_f32(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::f64_const(
F64(0x8000000000000000UL.reinterpret_as_double()),
),
Instruction::f64_const(F64(0.0)),
Instruction::f64_max(),
Instruction::i64_reinterpret_f64(),
]),
),
]),
)
}
///|
fn gen_valid_precompute_gc_value_module() -> Module {
let array_type = TypeIdx::new(0U)
let packed_array_type = TypeIdx::new(1U)
let struct_type = TypeIdx::new(2U)
let packed_struct_type = TypeIdx::new(3U)
let func_type = TypeIdx::new(4U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::val_type(ValType::i32()), Mut::const_()),
),
),
),
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(
StorageType::pack_type(PackType::i8()),
Mut::const_(),
),
),
),
),
RecType::new(
SubType::comp_type(
CompType::struct_([
FieldType::new(StorageType::val_type(ValType::i32()), Mut::const_()),
]),
),
),
RecType::new(
SubType::comp_type(
CompType::struct_([
FieldType::new(
StorageType::pack_type(PackType::i8()),
Mut::const_(),
),
]),
),
),
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
]),
)
.with_func_sec(
FuncSec::new([
func_type, func_type, func_type, func_type, func_type, func_type, func_type,
func_type, func_type, func_type, func_type, func_type, func_type,
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(42)),
Instruction::array_new_fixed(array_type, U32(1U)),
Instruction::i32_const(I32(0)),
Instruction::array_get(array_type),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::array_new_default(array_type),
Instruction::array_len(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(255)),
Instruction::array_new_fixed(packed_array_type, U32(1U)),
Instruction::i32_const(I32(0)),
Instruction::array_get_s(packed_array_type),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::struct_new_default(struct_type),
Instruction::struct_get(struct_type, U32(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(255)),
Instruction::struct_new(packed_struct_type),
Instruction::struct_get_s(packed_struct_type, U32(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(3)),
Instruction::array_new(array_type),
Instruction::i32_const(I32(2)),
Instruction::array_get(array_type),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(-1)),
Instruction::array_new(array_type),
Instruction::i32_const(I32(0)),
Instruction::array_get(array_type),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(-1)),
Instruction::array_new(array_type),
Instruction::array_len(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(-1)),
Instruction::array_new_default(array_type),
Instruction::i32_const(I32(0)),
Instruction::array_get(array_type),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::array_new_fixed(array_type, U32(1U)),
Instruction::i32_const(I32(1)),
Instruction::array_get(array_type),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(44739241)),
Instruction::array_new(array_type),
Instruction::array_len(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(44739242)),
Instruction::array_new(array_type),
Instruction::array_len(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(44739242)),
Instruction::array_new(array_type),
Instruction::i32_const(I32(0)),
Instruction::array_get(array_type),
]),
),
]),
)
}
///|
fn gen_valid_precompute_effectful_value_module() -> Module {
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32()]),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::i32_const(I32(2)),
Instruction::i32_add(),
]),
),
]),
)
}
///|
fn gen_valid_precompute_gc_atomic_types() -> Array[RecType] {
let struct_type = RecType::new(
SubType::comp_type(
CompType::struct_([
FieldType::new(StorageType::pack_type(PackType::i8()), Mut::var_()),
]),
),
)
let array_type = RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::val_type(ValType::i32()), Mut::var_()),
),
),
)
let ref_ty = ValType::ref_type(
RefType::new(false, HeapType::new(TypeIdx::new(0U))),
)
let func_type = RecType::new(SubType::comp_type(CompType::func([ref_ty], [])))
let wrapper_type = gen_valid_precompute_void_func_type()
[struct_type, array_type, func_type, wrapper_type]
}
///|
fn gen_valid_precompute_gc_atomic_body() -> Array[Instruction] {
let body : Array[Instruction] = []
for order in [AtomicOrder::seq_cst(), AtomicOrder::acq_rel()] {
body.push(Instruction::local_get(LocalIdx::new(0U)))
body.push(
Instruction::struct_atomic_get_s(order, TypeIdx::new(0U), U32(0U)),
)
body.push(Instruction::drop())
}
body.append([
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(1)),
Instruction::array_new(TypeIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::array_get(TypeIdx::new(1U)),
Instruction::drop(),
])
body
}
///|
fn gen_valid_precompute_profile_module_unexported(
config : GenValidConfig,
) -> Module {
let kind = gen_valid_precompute_profile_kind(config)
if kind == PrecomputeScalarValueProfile {
return gen_valid_precompute_scalar_value_module()
}
if kind == PrecomputeGcValueProfile {
return gen_valid_precompute_gc_value_module()
}
if kind == PrecomputeEffectfulValueProfile {
return gen_valid_precompute_effectful_value_module()
}
if kind == PrecomputeControlProfile {
return gen_valid_precompute_control_module()
}
if kind == PrecomputeGcAtomicBoundaryProfile {
return Module::new()
.with_type_sec(TypeSec::new(gen_valid_precompute_gc_atomic_types()))
.with_func_sec(FuncSec::new([TypeIdx::new(2U), TypeIdx::new(3U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new(gen_valid_precompute_gc_atomic_body()),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::struct_new(TypeIdx::new(0U)),
Instruction::call(FuncIdx::new(0U)),
]),
),
]),
)
}
if kind == PrecomputePropagateLocalFactsProfile {
let func_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [])),
)
return Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::i32_const(I32(131)),
Instruction::i32_mul(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_add(),
Instruction::global_set(GlobalIdx::new(0U)),
]),
),
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i32(),
ValType::i32(),
ValType::i32(),
ValType::i32(),
ValType::i32(),
]),
Expr::new(gen_valid_precompute_propagate_local_facts_body()),
),
]),
)
}
if kind == PrecomputeEffectBoundaryProfile {
return Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
gen_valid_precompute_void_func_type(),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(42))]),
),
Func::new(
Locals::empty(),
Expr::new(gen_valid_precompute_effect_boundary_body()),
),
]),
)
}
let body = match kind {
PrecomputeControlProfile => gen_valid_precompute_control_body()
PrecomputeGlobalProfile => gen_valid_precompute_global_body()
PrecomputeDropCleanupProfile => gen_valid_precompute_drop_cleanup_body()
PrecomputeDirectPrefixWatchProfile =>
gen_valid_precompute_direct_prefix_watch_body()
_ => gen_valid_precompute_scalar_body()
}
let locals = if kind == PrecomputeDirectPrefixWatchProfile {
Locals::from_types([ValType::i32()])
} else {
Locals::empty()
}
let func_type = if kind == PrecomputeDirectPrefixWatchProfile {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()])))
} else {
gen_valid_precompute_void_func_type()
}
let mod = Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(CodeSec::new([Func::new(locals, Expr::new(body))]))
if kind == PrecomputeGlobalProfile {
mod.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::i32_const(I32(34))]),
),
Global::new(
GlobalType::new(ValType::i64(), false),
Expr::new([Instruction::i64_const(I64(0L))]),
),
Global::new(
GlobalType::new(ValType::externref(), false),
Expr::new([
Instruction::ref_null(HeapType::abs(AbsHeapType::extern_())),
]),
),
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
} else if kind == PrecomputeScalarProfile ||
kind == PrecomputeDropCleanupProfile {
mod.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
} else {
mod
}
}
///|
fn gen_valid_precompute_func_exports(indices : Array[UInt32]) -> Array[Export] {
indices.map(fn(index) {
Export::new(
Name::from_string("run-\{index}"),
ExternIdx::func(FuncIdx::new(index)),
)
})
}
///|
fn gen_valid_precompute_profile_module(config : GenValidConfig) -> Module {
let kind = gen_valid_precompute_profile_kind(config)
let mod_ = gen_valid_precompute_profile_module_unexported(config)
let exports = match kind {
PrecomputeScalarValueProfile =>
gen_valid_precompute_func_exports([
0U, 1U, 2U, 3U, 4U, 6U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 16U, 17U, 24U,
25U,
])
PrecomputeGcValueProfile =>
gen_valid_precompute_func_exports([0U, 1U, 2U, 3U, 4U, 5U, 9U])
PrecomputeControlProfile => {
let values = gen_valid_precompute_func_exports([0U, 1U])
values.push(
Export::new(
Name::from_string("checksum"),
ExternIdx::global(GlobalIdx::new(0U)),
),
)
values
}
PrecomputeGlobalProfile => {
let values = gen_valid_precompute_func_exports([0U])
values.append([
Export::new(
Name::from_string("global-0"),
ExternIdx::global(GlobalIdx::new(0U)),
),
Export::new(
Name::from_string("global-1"),
ExternIdx::global(GlobalIdx::new(1U)),
),
Export::new(
Name::from_string("global-2"),
ExternIdx::global(GlobalIdx::new(2U)),
),
Export::new(
Name::from_string("checksum"),
ExternIdx::global(GlobalIdx::new(3U)),
),
])
values
}
PrecomputeEffectBoundaryProfile =>
[
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
Export::new(
Name::from_string("memory"),
ExternIdx::mem(MemIdx::new(0U)),
),
Export::new(
Name::from_string("state"),
ExternIdx::global(GlobalIdx::new(0U)),
),
]
PrecomputeGcAtomicBoundaryProfile => gen_valid_precompute_func_exports([1U])
PrecomputePropagateLocalFactsProfile =>
[
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
Export::new(
Name::from_string("checksum"),
ExternIdx::global(GlobalIdx::new(0U)),
),
]
PrecomputeScalarProfile | PrecomputeDropCleanupProfile => {
let values = gen_valid_precompute_func_exports([0U])
values.push(
Export::new(
Name::from_string("checksum"),
ExternIdx::global(GlobalIdx::new(0U)),
),
)
values
}
_ => gen_valid_precompute_func_exports([0U])
}
mod_.with_export_sec(ExportSec::new(exports))
}
///|
fn gen_valid_inlining_optimizing_profile_config(
profile : GenValidProfile,
) -> GenValidConfig {
let base = GenValidConfig::coverage_forced_default()
let family_id = match profile {
InliningOptimizingDirectWrapperProfile => 1
InliningOptimizingParamSpillProfile => 2
InliningOptimizingReturnCallProfile => 3
InliningOptimizingCleanupPayoffProfile => 4
_ => 5
}
GenValidConfig::{
..base,
max_type_defs: 2,
max_imports: 0,
max_defined_funcs: 3,
max_tables: 0,
max_mems: 0,
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: if profile == InliningOptimizingParamSpillProfile {
2
} else {
1
},
max_results: 1,
max_locals: if profile == InliningOptimizingParamSpillProfile {
2
} else {
0
},
max_body_statements: 8 + family_id,
max_body_depth: 1,
max_module_byte_size_budget: Some(20000 + family_id),
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: false,
allow_globals: false,
allow_tags: false,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: true,
allow_call_indirect: false,
allow_tail_calls: true,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_const_expr_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
},
}
}
///|
fn gen_valid_is_inlining_optimizing_profile_config(
config : GenValidConfig,
) -> Bool {
config == GenValidConfig::for_profile(InliningOptimizingDirectWrapperProfile) ||
config == GenValidConfig::for_profile(InliningOptimizingParamSpillProfile) ||
config == GenValidConfig::for_profile(InliningOptimizingReturnCallProfile) ||
config == GenValidConfig::for_profile(InliningOptimizingCleanupPayoffProfile) ||
config == GenValidConfig::for_profile(InliningOptimizingAllProfile)
}
///|
fn gen_valid_inlining_optimizing_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(InliningOptimizingParamSpillProfile) {
InliningOptimizingParamSpillProfile
} else if config ==
GenValidConfig::for_profile(InliningOptimizingReturnCallProfile) {
InliningOptimizingReturnCallProfile
} else if config ==
GenValidConfig::for_profile(InliningOptimizingCleanupPayoffProfile) {
InliningOptimizingCleanupPayoffProfile
} else {
InliningOptimizingDirectWrapperProfile
}
}
///|
pub fn gen_valid_inlining_optimizing_profile_case_label(
profile : GenValidProfile,
_seed : UInt64,
) -> String? {
match profile {
InliningOptimizingDirectWrapperProfile =>
Some("inlining-optimizing:direct-wrapper")
InliningOptimizingParamSpillProfile =>
Some("inlining-optimizing:param-spill")
InliningOptimizingReturnCallProfile =>
Some("inlining-optimizing:return-call")
InliningOptimizingCleanupPayoffProfile =>
Some("inlining-optimizing:cleanup-payoff")
_ => None
}
}
///|
fn gen_valid_inlining_optimizing_i32_result_type(
params : Array[ValType],
) -> RecType {
RecType::new(SubType::comp_type(CompType::func(params, [ValType::i32()])))
}
///|
fn gen_valid_inlining_optimizing_void_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [])))
}
///|
fn gen_valid_inlining_optimizing_profile_module(
config : GenValidConfig,
) -> Module {
let kind = gen_valid_inlining_optimizing_profile_kind(config)
let run_export = ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(1U))),
])
match kind {
InliningOptimizingParamSpillProfile =>
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_inlining_optimizing_i32_result_type([
ValType::i32(),
ValType::i32(),
]),
gen_valid_inlining_optimizing_i32_result_type([]),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_export_sec(run_export)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::from_types([ValType::i32(), ValType::i32()]),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(2)),
Instruction::i32_add(),
Instruction::drop(),
Instruction::i32_const(I32(20)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(22)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
]),
),
]),
)
InliningOptimizingReturnCallProfile =>
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_inlining_optimizing_i32_result_type([ValType::i32()]),
gen_valid_inlining_optimizing_i32_result_type([]),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_export_sec(run_export)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(2)),
Instruction::i32_add(),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(1)),
Instruction::i32_add(),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(40)),
Instruction::return_call(FuncIdx::new(0U)),
]),
),
]),
)
InliningOptimizingCleanupPayoffProfile =>
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_inlining_optimizing_void_type(),
gen_valid_inlining_optimizing_i32_result_type([]),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_export_sec(run_export)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(9)), Instruction::drop()]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(2)),
Instruction::i32_add(),
Instruction::drop(),
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(41)),
Instruction::i32_const(I32(1)),
Instruction::i32_add(),
]),
),
]),
)
_ =>
Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_inlining_optimizing_i32_result_type([]),
gen_valid_inlining_optimizing_i32_result_type([]),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_export_sec(run_export)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(40)),
Instruction::i32_const(I32(2)),
Instruction::i32_add(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
]),
),
]),
)
}
}
///|
fn gen_valid_sgo_profile_config(profile : GenValidProfile) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let family_id = match profile {
SgoInitializerFoldingProfile => 1
SgoSameInitDeadSetProfile => 2
SgoReadOnlyToWriteProfile => 3
SgoStartupPropagationProfile => 4
SgoRuntimePropagationProfile => 5
SgoNestedCleanupProfile => 6
_ => 7
}
GenValidConfig::{
..base,
max_type_defs: 1,
max_imports: 0,
max_defined_funcs: if profile == SgoInitializerFoldingProfile ||
profile == SgoStartupPropagationProfile {
0
} else if profile == SgoNestedCleanupProfile {
2
} else {
1
},
max_tables: 0,
max_mems: if profile == SgoStartupPropagationProfile {
1
} else {
0
},
max_globals: if profile == SgoInitializerFoldingProfile {
2
} else {
1
},
max_tags: 0,
max_elems: 0,
max_datas: if profile == SgoStartupPropagationProfile {
1
} else {
0
},
max_params: 0,
max_results: if profile == SgoSameInitDeadSetProfile ||
profile == SgoRuntimePropagationProfile {
1
} else {
0
},
max_locals: 0,
max_body_statements: 8 + family_id,
max_body_depth: 2,
max_module_byte_size_budget: Some(18000 + family_id),
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: profile == SgoStartupPropagationProfile,
allow_globals: true,
allow_tags: false,
allow_start: false,
allow_elems: false,
allow_datas: profile == SgoStartupPropagationProfile,
allow_ref_types: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_const_expr_variants: true,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
},
}
}
///|
fn gen_valid_is_sgo_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(SgoInitializerFoldingProfile) ||
config == GenValidConfig::for_profile(SgoSameInitDeadSetProfile) ||
config == GenValidConfig::for_profile(SgoReadOnlyToWriteProfile) ||
config == GenValidConfig::for_profile(SgoStartupPropagationProfile) ||
config == GenValidConfig::for_profile(SgoRuntimePropagationProfile) ||
config == GenValidConfig::for_profile(SgoNestedCleanupProfile) ||
config == GenValidConfig::for_profile(SgoAllProfile)
}
///|
fn gen_valid_sgo_profile_kind(config : GenValidConfig) -> GenValidProfile {
if config == GenValidConfig::for_profile(SgoSameInitDeadSetProfile) {
SgoSameInitDeadSetProfile
} else if config == GenValidConfig::for_profile(SgoReadOnlyToWriteProfile) {
SgoReadOnlyToWriteProfile
} else if config == GenValidConfig::for_profile(SgoStartupPropagationProfile) {
SgoStartupPropagationProfile
} else if config == GenValidConfig::for_profile(SgoRuntimePropagationProfile) {
SgoRuntimePropagationProfile
} else if config == GenValidConfig::for_profile(SgoNestedCleanupProfile) {
SgoNestedCleanupProfile
} else {
SgoInitializerFoldingProfile
}
}
///|
fn gen_valid_sgo_void_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [])))
}
///|
fn gen_valid_sgo_i32_result_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()])))
}
///|
fn gen_valid_sgo_func_module(
result : Bool,
body : Array[Instruction],
) -> Module {
let ty = if result {
gen_valid_sgo_i32_result_type()
} else {
gen_valid_sgo_void_type()
}
Module::new()
.with_type_sec(TypeSec::new([ty]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]))
}
///|
fn gen_valid_sgo_profile_module(config : GenValidConfig) -> Module {
match gen_valid_sgo_profile_kind(config) {
SgoSameInitDeadSetProfile =>
gen_valid_sgo_func_module(true, [
Instruction::i32_const(I32(7)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::global_get(GlobalIdx::new(0U)),
]).with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(7))]),
),
]),
)
SgoReadOnlyToWriteProfile =>
gen_valid_sgo_func_module(false, [
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(1)),
Instruction::global_set(GlobalIdx::new(0U)),
],
None,
),
]).with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
SgoStartupPropagationProfile =>
Module::new()
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::i32_const(I32(4))]),
),
]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::global_get(GlobalIdx::new(0U))]),
),
b"x",
),
]),
)
SgoRuntimePropagationProfile =>
gen_valid_sgo_func_module(true, [
Instruction::i32_const(I32(9)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::global_get(GlobalIdx::new(0U)),
]).with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
SgoNestedCleanupProfile =>
gen_valid_sgo_func_module(false, [
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::drop(),
]).with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(7))]),
),
]),
)
_ =>
Module::new().with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([
Instruction::i32_const(I32(40)),
Instruction::i32_const(I32(2)),
Instruction::i32_add(),
]),
),
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::global_get(GlobalIdx::new(0U))]),
),
]),
)
}
}
///|
fn gen_valid_pgg_profile_config(profile : GenValidProfile) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let family_id = match profile {
PggDirectGlobalProfile => 1
PggCompoundGlobalProfile => 2
PggGcCompoundProfile => 3
PggDataOffsetProfile => 4
PggElemOffsetProfile => 5
_ => 6
}
let gc = profile == PggGcCompoundProfile
let compound = profile == PggCompoundGlobalProfile
let data = profile == PggDataOffsetProfile
let elem = profile == PggElemOffsetProfile
GenValidConfig::{
..base,
max_type_defs: if gc || elem {
1
} else {
0
},
max_imports: 0,
max_defined_funcs: if elem {
1
} else {
0
},
max_tables: if elem {
1
} else {
0
},
max_mems: if data {
1
} else {
0
},
max_globals: if gc || compound {
3
} else if data || elem {
1
} else {
2
},
max_tags: 0,
max_elems: if elem {
1
} else {
0
},
max_datas: if data {
1
} else {
0
},
max_params: 0,
max_results: 0,
max_locals: 0,
max_body_statements: 4,
max_body_depth: 1,
max_module_byte_size_budget: Some(18100 + family_id),
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: elem,
allow_mems: data,
allow_globals: true,
allow_tags: false,
allow_start: false,
allow_elems: elem,
allow_datas: data,
allow_ref_types: gc || elem,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: false,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_const_expr_variants: true,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: false,
allow_subtyping_topology: false,
allow_name_custom_sections: false,
allow_typed_body_generator: false,
},
}
}
///|
fn gen_valid_is_pgg_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(PggDirectGlobalProfile) ||
config == GenValidConfig::for_profile(PggCompoundGlobalProfile) ||
config == GenValidConfig::for_profile(PggGcCompoundProfile) ||
config == GenValidConfig::for_profile(PggDataOffsetProfile) ||
config == GenValidConfig::for_profile(PggElemOffsetProfile) ||
config == GenValidConfig::for_profile(PggAllProfile)
}
///|
fn gen_valid_pgg_profile_kind(config : GenValidConfig) -> GenValidProfile {
if config == GenValidConfig::for_profile(PggCompoundGlobalProfile) {
PggCompoundGlobalProfile
} else if config == GenValidConfig::for_profile(PggGcCompoundProfile) {
PggGcCompoundProfile
} else if config == GenValidConfig::for_profile(PggDataOffsetProfile) {
PggDataOffsetProfile
} else if config == GenValidConfig::for_profile(PggElemOffsetProfile) {
PggElemOffsetProfile
} else {
PggDirectGlobalProfile
}
}
///|
fn gen_valid_pgg_i32_global(value : Int32) -> Global {
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::i32_const(I32(value))]),
)
}
///|
fn gen_valid_pgg_global_profile_module(
seed : UInt64,
compound : Bool,
) -> Module {
let value = (seed % 97UL).to_int() + 1
let dependent_init = if compound {
Expr::new([
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::i32_const(I32((seed % 11UL).to_int() + 1)),
Instruction::i32_add(),
])
} else {
Expr::new([Instruction::global_get(GlobalIdx::new(0U))])
}
let globals = [
gen_valid_pgg_i32_global(value),
Global::new(GlobalType::new(ValType::i32(), false), dependent_init),
]
if compound {
globals.push(
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::global_get(GlobalIdx::new(1U))]),
),
)
}
Module::new().with_global_sec(GlobalSec::new(globals))
}
///|
fn gen_valid_pgg_gc_compound_module(seed : UInt64) -> Module {
let pair_type = TypeIdx::new(0U)
let i32_field = fn() {
FieldType::new(StorageType::val_type(ValType::i32()), Const)
}
let left = (seed % 97UL).to_int() + 1
let right = (seed / 97UL % 89UL).to_int() + 1
let pair_ref = ValType::ref_type(
RefType::new(false, HeapType::new(pair_type)),
)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(
SubType::comp_type(CompType::struct_([i32_field(), i32_field()])),
),
]),
)
.with_global_sec(
GlobalSec::new([
gen_valid_pgg_i32_global(left),
gen_valid_pgg_i32_global(right),
Global::new(
GlobalType::new(pair_ref, false),
Expr::new([
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::global_get(GlobalIdx::new(1U)),
Instruction::struct_new(pair_type),
]),
),
]),
)
}
///|
fn gen_valid_pgg_data_offset_module(seed : UInt64) -> Module {
let offset = (seed % 64UL).to_int()
Module::new()
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_global_sec(GlobalSec::new([gen_valid_pgg_i32_global(offset)]))
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::global_get(GlobalIdx::new(0U))]),
),
b"pgg-data",
),
]),
)
}
///|
fn gen_valid_pgg_elem_offset_module(seed : UInt64) -> Module {
let offset = (seed % 16UL).to_int()
let funcref = RefType::new(true, HeapType::abs(AbsHeapType::func()))
Module::new()
.with_type_sec(
TypeSec::new([RecType::new(SubType::comp_type(CompType::func([], [])))]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_table_sec(
TableSec::new([
Table::new(TableType::new(funcref, Limits::i32(32U, None)), None),
]),
)
.with_global_sec(GlobalSec::new([gen_valid_pgg_i32_global(offset)]))
.with_elem_sec(
ElemSec::new([
Elem::new(
ElemMode::active(
TableIdx::new(0U),
Expr::new([Instruction::global_get(GlobalIdx::new(0U))]),
),
ElemKind::funcs([FuncIdx::new(0U)]),
),
]),
)
.with_code_sec(CodeSec::new([Func::new(Locals::empty(), Expr::new([]))]))
}
///|
fn gen_valid_pgg_profile_module(ctx : GenValidContext) -> Module {
match gen_valid_pgg_profile_kind(ctx.config) {
PggCompoundGlobalProfile =>
gen_valid_pgg_global_profile_module(ctx.root_seed, true)
PggGcCompoundProfile => gen_valid_pgg_gc_compound_module(ctx.root_seed)
PggDataOffsetProfile => gen_valid_pgg_data_offset_module(ctx.root_seed)
PggElemOffsetProfile => gen_valid_pgg_elem_offset_module(ctx.root_seed)
_ => gen_valid_pgg_global_profile_module(ctx.root_seed, false)
}
}
///|
fn gen_valid_once_reduction_profile_config() -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
GenValidConfig::{
..base,
max_type_defs: 1,
max_imports: 0,
max_defined_funcs: 8,
max_tables: 1,
max_mems: 0,
max_globals: 2,
max_tags: 0,
max_elems: 1,
max_datas: 0,
max_params: 0,
max_results: 0,
max_locals: 0,
max_body_statements: 8,
max_body_depth: 2,
max_module_byte_size_budget: Some(200000),
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: true,
allow_mems: false,
allow_globals: true,
allow_tags: false,
allow_elems: true,
allow_datas: false,
allow_calls: true,
allow_call_indirect: true,
allow_tail_calls: true,
allow_v128: false,
allow_relaxed_simd: false,
allow_memory64: false,
allow_atomics: false,
allow_typed_body_generator: true,
allow_name_custom_sections: false,
},
}
}
///|
fn gen_valid_is_once_reduction_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(OnceReductionTailCallsProfile)
}
///|
fn gen_valid_once_reduction_guard_body(
global_idx : GlobalIdx,
payload : Instruction?,
) -> Array[Instruction] {
let body : Array[Instruction] = [
Instruction::global_get(global_idx),
Instruction::if_(BlockType::void_(), [Instruction::return_()], None),
Instruction::i32_const(I32(1)),
Instruction::global_set(global_idx),
]
match payload {
Some(instr) => body.push(instr)
None => ()
}
body
}
///|
fn gen_valid_once_reduction_profile_module() -> Module {
let void_type = TypeIdx::new(0U)
let funcref = RefType::new(true, HeapType::abs(AbsHeapType::func()))
Module::new()
.with_type_sec(
TypeSec::new([RecType::new(SubType::comp_type(CompType::func([], [])))]),
)
.with_func_sec(
FuncSec::new([
void_type, void_type, void_type, void_type, void_type, void_type, void_type,
void_type,
]),
)
.with_table_sec(
TableSec::new([
Table::new(TableType::new(funcref, Limits::i32(1U, Some(1U))), None),
]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("summary"),
ExternIdx::func(FuncIdx::new(3U)),
),
Export::new(
Name::from_string("terminal"),
ExternIdx::func(FuncIdx::new(7U)),
),
]),
)
.with_elem_sec(
ElemSec::new([
Elem::new(ElemMode::declarative(), ElemKind::funcs([FuncIdx::new(0U)])),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([])),
Func::new(
Locals::empty(),
Expr::new(gen_valid_once_reduction_guard_body(GlobalIdx::new(0U), None)),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::return_call(FuncIdx::new(1U))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(2U)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Func::new(
Locals::empty(),
Expr::new(
gen_valid_once_reduction_guard_body(
GlobalIdx::new(1U),
Some(Instruction::return_call(FuncIdx::new(1U))),
),
),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::return_call_indirect(void_type, TableIdx::new(0U)),
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::drop(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_func(FuncIdx::new(0U)),
Instruction::return_call_ref(void_type),
Instruction::i32_const(I32(0)),
Instruction::global_set(GlobalIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::call(FuncIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_vacuum_profile_config(profile : GenValidProfile) -> GenValidConfig {
if profile == VacuumUnreadTeeProfile {
return gen_valid_vacuum_unread_tee_config()
}
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let family_id = match profile {
VacuumCoreProfile => 1
VacuumTerminalUnreachableProfile => 2
VacuumStructuralWrappersProfile => 3
VacuumDroppedParentEffectsProfile => 4
VacuumConstantResultIfProfile => 5
VacuumCallPrefixContinuationProfile => 6
VacuumLocalsetPrefixPreserveProfile => 7
VacuumHazardBoundaryProfile => 8
_ => 0
}
GenValidConfig::{
..base,
max_type_defs: if profile == VacuumHazardBoundaryProfile ||
profile == VacuumCallPrefixContinuationProfile ||
profile == VacuumLocalsetPrefixPreserveProfile ||
profile == VacuumDroppedParentEffectsProfile ||
profile == VacuumConstantResultIfProfile {
4
} else {
1
},
max_imports: 0,
max_defined_funcs: if profile == VacuumHazardBoundaryProfile {
4
} else if profile == VacuumDroppedParentEffectsProfile {
5
} else if profile == VacuumConstantResultIfProfile {
7
} else if profile == VacuumCallPrefixContinuationProfile {
2
} else if profile == VacuumLocalsetPrefixPreserveProfile {
3
} else {
2
},
max_tables: 0,
max_mems: if profile == VacuumHazardBoundaryProfile {
1
} else {
0
},
max_globals: 0,
max_tags: 0,
max_elems: 0,
max_datas: 0,
max_params: if profile == VacuumLocalsetPrefixPreserveProfile {
1
} else {
0
},
max_results: if profile == VacuumHazardBoundaryProfile ||
profile == VacuumDroppedParentEffectsProfile ||
profile == VacuumConstantResultIfProfile ||
profile == VacuumCallPrefixContinuationProfile ||
profile == VacuumLocalsetPrefixPreserveProfile {
1
} else {
0
},
max_locals: if profile == VacuumHazardBoundaryProfile ||
profile == VacuumCallPrefixContinuationProfile ||
profile == VacuumLocalsetPrefixPreserveProfile ||
profile == VacuumStructuralWrappersProfile {
1
} else {
0
},
max_body_statements: 13 + family_id,
max_body_depth: 3,
max_module_byte_size_budget: Some(200000 + family_id),
features: GenValidFeatureToggles::{
..base.features,
allow_imports: false,
allow_tables: false,
allow_mems: profile == VacuumHazardBoundaryProfile,
allow_globals: false,
allow_tags: false,
allow_elems: false,
allow_datas: false,
allow_calls: profile == VacuumHazardBoundaryProfile ||
profile == VacuumDroppedParentEffectsProfile ||
profile == VacuumConstantResultIfProfile ||
profile == VacuumCallPrefixContinuationProfile ||
profile == VacuumLocalsetPrefixPreserveProfile ||
profile == VacuumStructuralWrappersProfile,
allow_call_indirect: false,
allow_tail_calls: false,
allow_v128: false,
allow_relaxed_simd: false,
allow_memory64: false,
allow_atomics: false,
allow_typed_body_generator: true,
allow_name_custom_sections: false,
},
}
}
///|
fn gen_valid_is_vacuum_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(VacuumProfile) ||
config == GenValidConfig::for_profile(VacuumCoreProfile) ||
config == GenValidConfig::for_profile(VacuumTerminalUnreachableProfile) ||
config == GenValidConfig::for_profile(VacuumStructuralWrappersProfile) ||
config == GenValidConfig::for_profile(VacuumDroppedParentEffectsProfile) ||
config == GenValidConfig::for_profile(VacuumConstantResultIfProfile) ||
config == GenValidConfig::for_profile(VacuumCallPrefixContinuationProfile) ||
config == GenValidConfig::for_profile(VacuumLocalsetPrefixPreserveProfile) ||
config == GenValidConfig::for_profile(VacuumHazardBoundaryProfile) ||
config == GenValidConfig::for_profile(VacuumUnreadTeeProfile)
}
///|
fn gen_valid_vacuum_profile_kind(config : GenValidConfig) -> GenValidProfile {
if config == GenValidConfig::for_profile(VacuumUnreadTeeProfile) {
return VacuumUnreadTeeProfile
}
if config == GenValidConfig::for_profile(VacuumTerminalUnreachableProfile) {
VacuumTerminalUnreachableProfile
} else if config ==
GenValidConfig::for_profile(VacuumStructuralWrappersProfile) {
VacuumStructuralWrappersProfile
} else if config ==
GenValidConfig::for_profile(VacuumDroppedParentEffectsProfile) {
VacuumDroppedParentEffectsProfile
} else if config == GenValidConfig::for_profile(VacuumConstantResultIfProfile) {
VacuumConstantResultIfProfile
} else if config ==
GenValidConfig::for_profile(VacuumCallPrefixContinuationProfile) {
VacuumCallPrefixContinuationProfile
} else if config ==
GenValidConfig::for_profile(VacuumLocalsetPrefixPreserveProfile) {
VacuumLocalsetPrefixPreserveProfile
} else if config == GenValidConfig::for_profile(VacuumHazardBoundaryProfile) {
VacuumHazardBoundaryProfile
} else {
VacuumCoreProfile
}
}
///|
fn gen_valid_vacuum_profile_small_body() -> Array[Instruction] {
[
Instruction::nop(),
Instruction::i32_const(I32(7)),
Instruction::drop(),
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::i32_const(I32(8)), Instruction::drop()],
Some([Instruction::i32_const(I32(9)), Instruction::drop()]),
),
Instruction::i32_const(I32(0)),
Instruction::if_(
BlockType::void_(),
[],
Some([Instruction::i32_const(I32(10)), Instruction::drop()]),
),
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::unreachable_()]),
),
Instruction::block(BlockType::void_(), Expr::new([])),
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::nop(),
Instruction::i64_const(I64(11L)),
Instruction::drop(),
Instruction::f32_const(F32(1.0)),
Instruction::drop(),
Instruction::f64_const(F64(2.0)),
Instruction::drop(),
Instruction::ref_null(HeapType::abs(AbsHeapType::extern_())),
Instruction::drop(),
]),
),
]
}
///|
fn gen_valid_vacuum_profile_large_body() -> Array[Instruction] {
let body : Array[Instruction] = []
let mut idx = 0
while idx < 128 {
body.push(Instruction::i32_const(I32(idx)))
body.push(Instruction::drop())
if idx % 8 == 0 {
body.push(Instruction::nop())
}
idx += 1
}
body.push(Instruction::i32_const(I32(1)))
body.push(
Instruction::if_(
BlockType::void_(),
[Instruction::i32_const(I32(17)), Instruction::drop()],
Some([Instruction::i32_const(I32(18)), Instruction::drop()]),
),
)
body.push(Instruction::unreachable_())
body
}
///|
fn gen_valid_vacuum_terminal_unreachable_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(21)),
Instruction::drop(),
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i64_const(I64(22L)),
Instruction::drop(),
Instruction::unreachable_(),
]),
),
Instruction::unreachable_(),
]
}
///|
fn gen_valid_vacuum_structural_wrappers_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::block(BlockType::void_(), Expr::new([])),
Instruction::nop(),
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::i32_const(I32(23)), Instruction::drop()],
Some([]),
),
]),
),
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::unreachable_()]),
),
Instruction::i32_const(I32(0)),
Instruction::if_(
BlockType::void_(),
[],
Some([Instruction::i32_const(I32(24)), Instruction::drop()]),
),
]
}
///|
fn gen_valid_vacuum_deep_singleton_call_leaf_body() -> Array[Instruction] {
let mut body : Array[Instruction] = [
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(0U)),
]
for level = 0; level < 64; level = level + 1 {
body = [Instruction::block(BlockType::void_(), Expr::new(body))]
}
body
}
///|
fn gen_valid_vacuum_core_profile_module() -> Module {
let void_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(TypeSec::new([void_func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new(gen_valid_vacuum_profile_small_body()),
),
Func::new(
Locals::empty(),
Expr::new(gen_valid_vacuum_profile_large_body()),
),
]),
)
}
///|
fn gen_valid_vacuum_terminal_unreachable_profile_module() -> Module {
let void_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(TypeSec::new([void_func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new(gen_valid_vacuum_terminal_unreachable_body()),
),
]),
)
}
///|
fn gen_valid_vacuum_structural_wrappers_profile_module() -> Module {
let void_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(TypeSec::new([void_func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new(gen_valid_vacuum_structural_wrappers_body()),
),
Func::new(
Locals::single(1U, ValType::i32()),
Expr::new(gen_valid_vacuum_deep_singleton_call_leaf_body()),
),
]),
)
}
///|
fn gen_valid_vacuum_dropped_parent_effects_op(seed : UInt64) -> Instruction {
match (seed % 4UL).to_int() {
0 => Instruction::i32_add()
1 => Instruction::i32_xor()
2 => Instruction::i32_mul()
_ => Instruction::i32_lt_s()
}
}
///|
fn gen_valid_vacuum_dropped_parent_effects_profile_module(
seed : UInt64,
) -> Module {
let value = (seed % 97UL).to_int() + 1
let parent_op = gen_valid_vacuum_dropped_parent_effects_op(seed)
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let void_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(TypeSec::new([i32_func_type, void_func_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(1U),
TypeIdx::new(1U),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(value))]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(value + 1))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(0U)),
Instruction::call(FuncIdx::new(1U)),
parent_op,
Instruction::drop(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(value + 2)),
parent_op,
Instruction::drop(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(0U)),
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::i32_div_s(),
parent_op,
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_vacuum_constant_result_if_profile_module(seed : UInt64) -> Module {
let condition = if seed % 2UL == 0UL { 0 } else { 1 }
let value = (seed % 101UL).to_int() + 100
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let void_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(TypeSec::new([i32_func_type, i64_func_type, void_func_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(0U),
TypeIdx::new(2U),
TypeIdx::new(2U),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(condition))]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(value + 6))]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(condition)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(value))],
Some([Instruction::i32_const(I32(value + 1))]),
),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(1 - condition)),
Instruction::if_(
BlockType::val_type(ValType::i64()),
[Instruction::i64_const(I64(value.to_int64() + 2L))],
Some([Instruction::i64_const(I64(value.to_int64() + 3L))]),
),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(condition)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(value + 4))],
Some([Instruction::i32_const(I32(value + 5))]),
),
]),
),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(0U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::unreachable_()],
Some([Instruction::call(FuncIdx::new(1U))]),
),
Instruction::drop(),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(FuncIdx::new(0U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::call(FuncIdx::new(1U))],
Some([Instruction::unreachable_()]),
),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_vacuum_call_prefix_continuation_profile_module() -> Module {
let void_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
Module::new()
.with_type_sec(TypeSec::new([i32_func_type, void_func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(1))])),
Func::new(
Locals::single(1U, ValType::i32()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::block(BlockType::void_(), Expr::new([])),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(0)),
Instruction::i32_sub(),
Instruction::drop(),
Instruction::call(FuncIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::call(FuncIdx::new(0U)), Instruction::drop()],
Some([]),
),
]),
),
Instruction::i32_const(I32(26)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::nop(),
]),
),
]),
)
}
///|
fn gen_valid_vacuum_localset_prefix_preserve_profile_module() -> Module {
let unary_i32_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [ValType::i32()])),
)
let consume_i32_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [])),
)
let void_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(
TypeSec::new([unary_i32_type, consume_i32_type, void_func_type]),
)
.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([Instruction::local_get(LocalIdx::new(0U))]),
),
Func::new(Locals::empty(), Expr::new([])),
Func::new(
Locals::single(1U, ValType::i32()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(27)),
Instruction::call(FuncIdx::new(0U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(1U)),
]),
),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(1U)),
],
Some([]),
),
]),
),
]),
)
}
///|
fn gen_valid_vacuum_hazard_boundary_profile_module() -> Module {
let alloc_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let void_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
Module::new()
.with_type_sec(TypeSec::new([alloc_type, void_func_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(1U),
TypeIdx::new(1U),
]),
)
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(0))])),
Func::new(Locals::empty(), Expr::new([])),
Func::new(Locals::empty(), Expr::new([])),
Func::new(
Locals::single(1U, ValType::i32()),
Expr::new([
Instruction::i32_const(I32(29)),
Instruction::drop(),
Instruction::call(FuncIdx::new(0U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(30)),
Instruction::i32_store(gen_valid_memarg()),
Instruction::call(FuncIdx::new(1U)),
Instruction::call(FuncIdx::new(2U)),
Instruction::i32_const(I32(31)),
Instruction::i32_const(I32(32)),
Instruction::i32_add(),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_vacuum_profile_module(ctx : GenValidContext) -> Module {
match gen_valid_vacuum_profile_kind(ctx.config) {
VacuumUnreadTeeProfile => gen_valid_vacuum_unread_tee_module(ctx.root_seed)
VacuumTerminalUnreachableProfile =>
gen_valid_vacuum_terminal_unreachable_profile_module()
VacuumStructuralWrappersProfile =>
gen_valid_vacuum_structural_wrappers_profile_module()
VacuumDroppedParentEffectsProfile =>
gen_valid_vacuum_dropped_parent_effects_profile_module(ctx.root_seed)
VacuumConstantResultIfProfile =>
gen_valid_vacuum_constant_result_if_profile_module(ctx.root_seed)
VacuumCallPrefixContinuationProfile =>
gen_valid_vacuum_call_prefix_continuation_profile_module()
VacuumLocalsetPrefixPreserveProfile =>
gen_valid_vacuum_localset_prefix_preserve_profile_module()
VacuumHazardBoundaryProfile =>
gen_valid_vacuum_hazard_boundary_profile_module()
_ => gen_valid_vacuum_core_profile_module()
}
}
///|
fn gen_valid_rse_profile_config(profile : GenValidProfile) -> GenValidConfig {
let base = GenValidConfig::binaryen_oracle_coverage_forced_default()
let family_id = match profile {
RseCoreSameValueProfile => 1
RseLocalCopySelfSetProfile => 2
RseCfgMergeProfile => 3
RseLoopFlowProfile => 4
RseRefinedGetProfile => 5
RseRefinementWrappersProfile => 6
RseAggregateRefinalizeProfile => 7
RseExceptionBoundariesProfile => 8
RseHazardBoundaryProfile => 9
RseVacuumTailProfile => 10
_ => 0
}
GenValidConfig::{
..base,
max_type_defs: if profile == RseRefinedGetProfile ||
profile == RseAggregateRefinalizeProfile ||
profile == RseExceptionBoundariesProfile {
4
} else {
1
},
max_imports: 0,
max_defined_funcs: 1,
max_tables: if profile == RseHazardBoundaryProfile {
1
} else {
0
},
max_mems: if profile == RseHazardBoundaryProfile {
1
} else {
0
},
max_globals: if profile == RseHazardBoundaryProfile {
2
} else {
0
},
max_tags: if profile == RseExceptionBoundariesProfile {
1
} else {
0
},
max_elems: 0,
max_datas: 0,
max_params: if profile == RseRefinedGetProfile ||
profile == RseRefinementWrappersProfile {
1
} else {
0
},
max_results: 0,
max_locals: if profile == RseAggregateRefinalizeProfile ||
profile == RseHazardBoundaryProfile {
4
} else {
3
},
max_body_statements: 18 + family_id,
max_body_depth: 4,
max_module_byte_size_budget: Some(230000 + family_id),
features: GenValidFeatureToggles::{
allow_imports: false,
allow_tables: profile == RseHazardBoundaryProfile,
allow_mems: profile == RseHazardBoundaryProfile,
allow_globals: profile == RseHazardBoundaryProfile,
allow_tags: profile == RseExceptionBoundariesProfile,
allow_start: false,
allow_elems: false,
allow_datas: false,
allow_ref_types: true,
allow_v128: false,
allow_relaxed_simd: false,
allow_calls: false,
allow_call_indirect: false,
allow_tail_calls: false,
allow_branch_heavy_control: profile == RseCfgMergeProfile ||
profile == RseLoopFlowProfile ||
profile == RseExceptionBoundariesProfile ||
profile == RseVacuumTailProfile,
allow_memory_limit_variants: false,
allow_table_limit_variants: false,
allow_const_expr_variants: false,
allow_shared_memories: false,
allow_memory64: false,
allow_atomics: profile == RseAggregateRefinalizeProfile,
allow_subtyping_topology: profile == RseRefinedGetProfile ||
profile == RseAggregateRefinalizeProfile,
allow_name_custom_sections: false,
allow_typed_body_generator: true,
allow_ssa_nomerge_body_generator: false,
allow_heap_store_optimization_body_generator: false,
allow_heap2local_body_generator: false,
},
}
}
///|
fn gen_valid_is_rse_profile_config(config : GenValidConfig) -> Bool {
config == GenValidConfig::for_profile(RseAllProfile) ||
config == GenValidConfig::for_profile(RseCoreSameValueProfile) ||
config == GenValidConfig::for_profile(RseLocalCopySelfSetProfile) ||
config == GenValidConfig::for_profile(RseCfgMergeProfile) ||
config == GenValidConfig::for_profile(RseLoopFlowProfile) ||
config == GenValidConfig::for_profile(RseRefinedGetProfile) ||
config == GenValidConfig::for_profile(RseRefinementWrappersProfile) ||
config == GenValidConfig::for_profile(RseAggregateRefinalizeProfile) ||
config == GenValidConfig::for_profile(RseExceptionBoundariesProfile) ||
config == GenValidConfig::for_profile(RseHazardBoundaryProfile) ||
config == GenValidConfig::for_profile(RseVacuumTailProfile)
}
///|
fn gen_valid_rse_profile_kind(config : GenValidConfig) -> GenValidProfile {
if config == GenValidConfig::for_profile(RseLocalCopySelfSetProfile) {
RseLocalCopySelfSetProfile
} else if config == GenValidConfig::for_profile(RseCfgMergeProfile) {
RseCfgMergeProfile
} else if config == GenValidConfig::for_profile(RseLoopFlowProfile) {
RseLoopFlowProfile
} else if config == GenValidConfig::for_profile(RseRefinedGetProfile) {
RseRefinedGetProfile
} else if config == GenValidConfig::for_profile(RseRefinementWrappersProfile) {
RseRefinementWrappersProfile
} else if config == GenValidConfig::for_profile(RseAggregateRefinalizeProfile) {
RseAggregateRefinalizeProfile
} else if config == GenValidConfig::for_profile(RseExceptionBoundariesProfile) {
RseExceptionBoundariesProfile
} else if config == GenValidConfig::for_profile(RseHazardBoundaryProfile) {
RseHazardBoundaryProfile
} else if config == GenValidConfig::for_profile(RseVacuumTailProfile) {
RseVacuumTailProfile
} else {
RseCoreSameValueProfile
}
}
///|
fn gen_valid_rse_func_type(
params : Array[ValType],
results : Array[ValType],
) -> RecType {
RecType::new(SubType::comp_type(CompType::func(params, results)))
}
///|
fn gen_valid_rse_i32_void_module(
locals : Array[ValType],
body : Array[Instruction],
) -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_rse_func_type([], [])]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([Func::new(Locals::from_types(locals), Expr::new(body))]),
)
}
///|
fn gen_valid_rse_core_same_value_profile_module() -> Module {
gen_valid_rse_i32_void_module([ValType::i32(), ValType::i32()], [
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::i32_const(I32(13)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(14)),
Instruction::local_set(LocalIdx::new(1U)),
])
}
///|
fn gen_valid_rse_local_copy_self_set_profile_module() -> Module {
gen_valid_rse_i32_void_module(
[ValType::i32(), ValType::i32(), ValType::i32()],
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
],
)
}
///|
fn gen_valid_rse_cfg_merge_profile_module() -> Module {
gen_valid_rse_i32_void_module([ValType::i32(), ValType::i32()], [
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(1)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(1)),
Instruction::local_set(LocalIdx::new(1U)),
],
Some([
Instruction::i32_const(I32(1)),
Instruction::local_set(LocalIdx::new(1U)),
]),
),
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(2)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(2)),
Instruction::local_set(LocalIdx::new(1U)),
]),
),
])
}
///|
fn gen_valid_rse_loop_flow_profile_module() -> Module {
gen_valid_rse_i32_void_module([ValType::i32()], [
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(3)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(3)),
Instruction::local_set(LocalIdx::new(0U)),
]),
),
Instruction::i32_const(I32(4)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::i32_const(I32(4)),
Instruction::local_set(LocalIdx::new(0U)),
]),
),
])
}
///|
fn gen_valid_rse_refined_get_profile_module() -> Module {
let base_ty = RecType::new(SubType::new(false, [], CompType::struct_([])))
let child_ty = RecType::new(
SubType::new(false, [TypeIdx::new(0U)], CompType::struct_([])),
)
let child_ref = ValType::ref_type(
RefType::new(true, HeapType::new(TypeIdx::new(1U))),
)
let base_ref = ValType::ref_type(
RefType::new(true, HeapType::new(TypeIdx::new(0U))),
)
let func_ty = gen_valid_rse_func_type([child_ref], [])
Module::new()
.with_type_sec(TypeSec::new([base_ty, child_ty, func_ty]))
.with_func_sec(FuncSec::new([TypeIdx::new(2U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([base_ref, child_ref]),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_rse_refinement_wrappers_profile_module() -> Module {
let any_heap = HeapType::abs(AbsHeapType::any())
let nullable_any = ValType::ref_type(RefType::new(true, any_heap))
let func_ty = gen_valid_rse_func_type([nullable_any], [])
Module::new()
.with_type_sec(TypeSec::new([func_ty]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([nullable_any, nullable_any]),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_as_non_null(),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::ref_cast(true, any_heap),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_rse_aggregate_refinalize_profile_module() -> Module {
let i32_field = FieldType::new(
StorageType::val_type(ValType::i32()),
Mut::var_(),
)
let i8_field = FieldType::new(
StorageType::pack_type(PackType::i8()),
Mut::var_(),
)
let struct_ty = RecType::new(
SubType::comp_type(CompType::struct_([i32_field, i8_field])),
)
let array_ty = RecType::new(SubType::comp_type(CompType::array(i32_field)))
let struct_ref = ValType::ref_type(
RefType::new(true, HeapType::new(TypeIdx::new(0U))),
)
let array_ref = ValType::ref_type(
RefType::new(true, HeapType::new(TypeIdx::new(1U))),
)
let func_ty = gen_valid_rse_func_type([], [])
Module::new()
.with_type_sec(TypeSec::new([struct_ty, array_ty, func_ty]))
.with_func_sec(FuncSec::new([TypeIdx::new(2U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([struct_ref, array_ref]),
Expr::new([
Instruction::struct_new_default(TypeIdx::new(0U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::struct_get(TypeIdx::new(0U), 0U),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::struct_get_s(TypeIdx::new(0U), 1U),
Instruction::drop(),
Instruction::i32_const(I32(4)),
Instruction::array_new_default(TypeIdx::new(1U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::array_get(TypeIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(9)),
Instruction::array_set(TypeIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_rse_exception_boundaries_profile_module() -> Module {
let tag_ty = gen_valid_rse_func_type([], [])
let func_ty = gen_valid_rse_func_type([], [])
Module::new()
.with_type_sec(TypeSec::new([tag_ty, func_ty]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(0U))]))
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32()]),
Expr::new([
Instruction::i32_const(I32(5)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(5)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::new(TagIdx::new(0U), LabelIdx::new(0U))],
Expr::new([Instruction::nop()]),
),
]),
),
Instruction::throw_(TagIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_rse_hazard_boundary_profile_module() -> Module {
let ma = MemArg::new(2U, None, 0UL)
gen_valid_rse_i32_void_module(
[
ValType::i32(),
ValType::ref_type(
RefType::new(true, HeapType::abs(AbsHeapType::extern_())),
),
],
[
Instruction::i32_const(I32(6)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(11)),
Instruction::i32_store(ma),
Instruction::i32_const(I32(6)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::ref_null(HeapType::abs(AbsHeapType::extern_())),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::table_set(TableIdx::new(0U)),
Instruction::i32_const(I32(12)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(6)),
Instruction::local_set(LocalIdx::new(0U)),
],
)
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_table_sec(
TableSec::new([
Table::new(
TableType::new(
RefType::new(true, HeapType::abs(AbsHeapType::extern_())),
Limits::i32(1U, None),
),
None,
),
]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::i32_const(I32(1))]),
),
]),
)
}
///|
fn gen_valid_rse_vacuum_tail_profile_module() -> Module {
gen_valid_rse_i32_void_module([ValType::i32()], [
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(8)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(8)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::block(BlockType::void_(), Expr::new([])),
Instruction::nop(),
]),
),
Instruction::i32_const(I32(8)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(8)),
Instruction::local_set(LocalIdx::new(0U)),
])
}
///|
fn gen_valid_rse_profile_module(config : GenValidConfig) -> Module {
match gen_valid_rse_profile_kind(config) {
RseLocalCopySelfSetProfile =>
gen_valid_rse_local_copy_self_set_profile_module()
RseCfgMergeProfile => gen_valid_rse_cfg_merge_profile_module()
RseLoopFlowProfile => gen_valid_rse_loop_flow_profile_module()
RseRefinedGetProfile => gen_valid_rse_refined_get_profile_module()
RseRefinementWrappersProfile =>
gen_valid_rse_refinement_wrappers_profile_module()
RseAggregateRefinalizeProfile =>
gen_valid_rse_aggregate_refinalize_profile_module()
RseExceptionBoundariesProfile =>
gen_valid_rse_exception_boundaries_profile_module()
RseHazardBoundaryProfile => gen_valid_rse_hazard_boundary_profile_module()
RseVacuumTailProfile => gen_valid_rse_vacuum_tail_profile_module()
_ => gen_valid_rse_core_same_value_profile_module()
}
}
///|
fn gen_valid_pick_load_signs_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(PickLoadSignsSignedShiftProfile) {
PickLoadSignsSignedShiftProfile
} else if config ==
GenValidConfig::for_profile(PickLoadSignsUnsignedMaskProfile) {
PickLoadSignsUnsignedMaskProfile
} else if config ==
GenValidConfig::for_profile(PickLoadSignsUnsignedShiftProfile) {
PickLoadSignsUnsignedShiftProfile
} else if config ==
GenValidConfig::for_profile(PickLoadSignsUnknownUseBoundaryProfile) {
PickLoadSignsUnknownUseBoundaryProfile
} else if config ==
GenValidConfig::for_profile(PickLoadSignsMixedWidthBoundaryProfile) {
PickLoadSignsMixedWidthBoundaryProfile
} else if config ==
GenValidConfig::for_profile(PickLoadSignsWidthMismatchBoundaryProfile) {
PickLoadSignsWidthMismatchBoundaryProfile
} else if config ==
GenValidConfig::for_profile(PickLoadSignsTeeBoundaryProfile) {
PickLoadSignsTeeBoundaryProfile
} else if config ==
GenValidConfig::for_profile(PickLoadSignsNoMemoryBoundaryProfile) {
PickLoadSignsNoMemoryBoundaryProfile
} else if config ==
GenValidConfig::for_profile(PickLoadSignsImportedMemoryProfile) {
PickLoadSignsImportedMemoryProfile
} else if config == GenValidConfig::for_profile(PickLoadSignsI64WatchProfile) {
PickLoadSignsI64WatchProfile
} else {
PickLoadSignsSignedExtendProfile
}
}
///|
fn gen_valid_pick_load_signs_memarg() -> MemArg {
MemArg::new(0U, None, 0UL)
}
///|
fn gen_valid_pick_load_signs_i32_body(
kind : GenValidProfile,
) -> Array[Instruction] {
let ma = gen_valid_pick_load_signs_memarg()
match kind {
PickLoadSignsSignedShiftProfile =>
[
Instruction::i32_const(I32(0)),
Instruction::i32_load8u(ma),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(24)),
Instruction::i32_shl(),
Instruction::i32_const(I32(24)),
Instruction::i32_shr_s(),
]
PickLoadSignsUnsignedMaskProfile =>
[
Instruction::i32_const(I32(0)),
Instruction::i32_load8s(ma),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(255)),
Instruction::i32_and(),
]
PickLoadSignsUnsignedShiftProfile =>
[
Instruction::i32_const(I32(0)),
Instruction::i32_load16s(ma),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(16)),
Instruction::i32_shl(),
Instruction::i32_const(I32(16)),
Instruction::i32_shr_u(),
]
PickLoadSignsUnknownUseBoundaryProfile =>
[
Instruction::i32_const(I32(0)),
Instruction::i32_load8u(ma),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(1)),
Instruction::i32_eq(),
]
PickLoadSignsMixedWidthBoundaryProfile =>
[
Instruction::i32_const(I32(0)),
Instruction::i32_load8u(ma),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_extend8s(),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_extend16s(),
]
PickLoadSignsWidthMismatchBoundaryProfile =>
[
Instruction::i32_const(I32(0)),
Instruction::i32_load16u(ma),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_extend8s(),
]
PickLoadSignsNoMemoryBoundaryProfile =>
[
Instruction::i32_const(I32(1)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
]
_ =>
[
Instruction::i32_const(I32(0)),
Instruction::i32_load8u(ma),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_extend8s(),
]
}
}
///|
fn gen_valid_pick_load_signs_tee_body() -> Array[Instruction] {
let ma = gen_valid_pick_load_signs_memarg()
[
Instruction::i32_const(I32(0)),
Instruction::i32_load8u(ma),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_extend8s(),
Instruction::drop(),
Instruction::drop(),
]
}
///|
fn gen_valid_pick_load_signs_unsigned_mask_i32_body(
commuted : Bool,
) -> Array[Instruction] {
let ma = gen_valid_pick_load_signs_memarg()
let prefix = [
Instruction::i32_const(I32(0)),
Instruction::i32_load8s(ma),
Instruction::local_set(LocalIdx::new(0U)),
]
if commuted {
prefix +
[
Instruction::i32_const(I32(255)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_and(),
]
} else {
prefix +
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(255)),
Instruction::i32_and(),
]
}
}
///|
fn gen_valid_pick_load_signs_unsigned_mask_i64_body(
load_bits : Int32,
) -> Array[Instruction] {
let ma = gen_valid_pick_load_signs_memarg()
let (load, mask) = if load_bits == 8 {
(Instruction::i64_load8s(ma), 255L)
} else if load_bits == 16 {
(Instruction::i64_load16s(ma), 65535L)
} else {
(Instruction::i64_load32s(ma), 4294967295L)
}
[
Instruction::i32_const(I32(0)),
load,
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_const(I64(mask)),
Instruction::i64_and(),
]
}
///|
fn gen_valid_pick_load_signs_unsigned_mask_module() -> Module {
let i32_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let funcs = [
Func::new(
Locals::from_types([ValType::i32()]),
Expr::new(gen_valid_pick_load_signs_unsigned_mask_i32_body(false)),
),
Func::new(
Locals::from_types([ValType::i32()]),
Expr::new(gen_valid_pick_load_signs_unsigned_mask_i32_body(true)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_unsigned_mask_i64_body(8)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_unsigned_mask_i64_body(16)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_unsigned_mask_i64_body(32)),
),
]
Module::new()
.with_type_sec(TypeSec::new([i32_type, i64_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(1U),
TypeIdx::new(1U),
]),
)
.with_code_sec(CodeSec::new(funcs))
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
}
///|
fn gen_valid_pick_load_signs_i64_direct_body(
load_bits : Int32,
) -> Array[Instruction] {
let ma = gen_valid_pick_load_signs_memarg()
let (load, extension) = if load_bits == 8 {
(Instruction::i64_load8u(ma), Instruction::i64_extend8s())
} else if load_bits == 16 {
(Instruction::i64_load16u(ma), Instruction::i64_extend16s())
} else {
(Instruction::i64_load32u(ma), Instruction::i64_extend32s())
}
[
Instruction::i32_const(I32(0)),
load,
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
extension,
]
}
///|
fn gen_valid_pick_load_signs_i64_signed_shift_body(
load_bits : Int32,
) -> Array[Instruction] {
let ma = gen_valid_pick_load_signs_memarg()
let (load, shift) = if load_bits == 8 {
(Instruction::i64_load8u(ma), 56)
} else if load_bits == 16 {
(Instruction::i64_load16u(ma), 48)
} else {
(Instruction::i64_load32u(ma), 32)
}
[
Instruction::i32_const(I32(0)),
load,
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_const(I64(shift.to_int64())),
Instruction::i64_shl(),
Instruction::i64_const(I64(shift.to_int64())),
Instruction::i64_shr_s(),
]
}
///|
fn gen_valid_pick_load_signs_i64_watch_module() -> Module {
let i64_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let funcs = [
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_i64_direct_body(8)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_i64_direct_body(16)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_i64_direct_body(32)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_i64_signed_shift_body(8)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_i64_signed_shift_body(16)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_i64_signed_shift_body(32)),
),
]
Module::new()
.with_type_sec(TypeSec::new([i64_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
]),
)
.with_code_sec(CodeSec::new(funcs))
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
}
///|
fn gen_valid_pick_load_signs_unsigned_shift_i32_body(
load_bits : Int32,
) -> Array[Instruction] {
let ma = gen_valid_pick_load_signs_memarg()
let (load, shift) = if load_bits == 8 {
(Instruction::i32_load8s(ma), 24)
} else {
(Instruction::i32_load16s(ma), 16)
}
[
Instruction::i32_const(I32(0)),
load,
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(shift)),
Instruction::i32_shl(),
Instruction::i32_const(I32(shift)),
Instruction::i32_shr_u(),
]
}
///|
fn gen_valid_pick_load_signs_unsigned_shift_i64_body(
load_bits : Int32,
) -> Array[Instruction] {
let ma = gen_valid_pick_load_signs_memarg()
let (load, shift) = if load_bits == 8 {
(Instruction::i64_load8s(ma), 56)
} else if load_bits == 16 {
(Instruction::i64_load16s(ma), 48)
} else {
(Instruction::i64_load32s(ma), 32)
}
[
Instruction::i32_const(I32(0)),
load,
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_const(I64(shift.to_int64())),
Instruction::i64_shl(),
Instruction::i64_const(I64(shift.to_int64())),
Instruction::i64_shr_u(),
]
}
///|
fn gen_valid_pick_load_signs_unsigned_shift_module() -> Module {
let i32_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let funcs = [
Func::new(
Locals::from_types([ValType::i32()]),
Expr::new(gen_valid_pick_load_signs_unsigned_shift_i32_body(8)),
),
Func::new(
Locals::from_types([ValType::i32()]),
Expr::new(gen_valid_pick_load_signs_unsigned_shift_i32_body(16)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_unsigned_shift_i64_body(8)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_unsigned_shift_i64_body(16)),
),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(gen_valid_pick_load_signs_unsigned_shift_i64_body(32)),
),
]
Module::new()
.with_type_sec(TypeSec::new([i32_type, i64_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(1U),
TypeIdx::new(1U),
]),
)
.with_code_sec(CodeSec::new(funcs))
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
}
///|
fn gen_valid_pick_load_signs_profile_module(config : GenValidConfig) -> Module {
let kind = gen_valid_pick_load_signs_profile_kind(config)
if kind == PickLoadSignsUnsignedMaskProfile {
return gen_valid_pick_load_signs_unsigned_mask_module()
}
if kind == PickLoadSignsUnsignedShiftProfile {
return gen_valid_pick_load_signs_unsigned_shift_module()
}
if kind == PickLoadSignsI64WatchProfile {
return gen_valid_pick_load_signs_i64_watch_module()
}
let is_tee = kind == PickLoadSignsTeeBoundaryProfile
let result_type = if is_tee { [] } else { [ValType::i32()] }
let local_type = ValType::i32()
let body = if is_tee {
gen_valid_pick_load_signs_tee_body()
} else {
gen_valid_pick_load_signs_i32_body(kind)
}
let func_type = RecType::new(
SubType::comp_type(CompType::func([], result_type)),
)
let func = Func::new(Locals::from_types([local_type]), Expr::new(body))
let mod = Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(CodeSec::new([func]))
if kind == PickLoadSignsNoMemoryBoundaryProfile {
mod
} else if kind == PickLoadSignsImportedMemoryProfile {
mod.with_import_sec(
ImportSec::new([
Import::new(
Name::new("env"),
Name::new("memory"),
ExternType::mem(MemType::new(Limits::i32(1U, None))),
),
]),
)
} else {
mod.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
}
}
///|
fn gen_valid_code_pushing_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(CodePushingAfterIfProfile) {
CodePushingAfterIfProfile
} else if config == GenValidConfig::for_profile(CodePushingDroppedIfProfile) {
CodePushingDroppedIfProfile
} else if config == GenValidConfig::for_profile(CodePushingBrIfProfile) {
CodePushingBrIfProfile
} else if config == GenValidConfig::for_profile(CodePushingBrOnNullProfile) {
CodePushingBrOnNullProfile
} else if config == GenValidConfig::for_profile(CodePushingBrOnNonNullProfile) {
CodePushingBrOnNonNullProfile
} else if config ==
GenValidConfig::for_profile(CodePushingBrOnNonNullPrefixProfile) {
CodePushingBrOnNonNullPrefixProfile
} else if config == GenValidConfig::for_profile(CodePushingBrOnCastProfile) {
CodePushingBrOnCastProfile
} else if config ==
GenValidConfig::for_profile(CodePushingBrOnCastFailProfile) {
CodePushingBrOnCastFailProfile
} else if config == GenValidConfig::for_profile(CodePushingBrIfValueProfile) {
CodePushingBrIfValueProfile
} else if config == GenValidConfig::for_profile(CodePushingMultiSetProfile) {
CodePushingMultiSetProfile
} else if config ==
GenValidConfig::for_profile(CodePushingMultiSetDroppedIfProfile) {
CodePushingMultiSetDroppedIfProfile
} else if config ==
GenValidConfig::for_profile(CodePushingMultiSetBrIfProfile) {
CodePushingMultiSetBrIfProfile
} else if config ==
GenValidConfig::for_profile(CodePushingMultiSetLocalCopyProfile) {
CodePushingMultiSetLocalCopyProfile
} else if config ==
GenValidConfig::for_profile(CodePushingMultiSetNopWindowProfile) {
CodePushingMultiSetNopWindowProfile
} else if config == GenValidConfig::for_profile(CodePushingLoopBrIfProfile) {
CodePushingLoopBrIfProfile
} else if config ==
GenValidConfig::for_profile(CodePushingMultiSetDropWindowProfile) {
CodePushingMultiSetDropWindowProfile
} else if config ==
GenValidConfig::for_profile(CodePushingMultiSetLocalGetWindowProfile) {
CodePushingMultiSetLocalGetWindowProfile
} else if config ==
GenValidConfig::for_profile(CodePushingMultiSetGlobalGetWindowProfile) {
CodePushingMultiSetGlobalGetWindowProfile
} else if config == GenValidConfig::for_profile(CodePushingZeroReadProfile) {
CodePushingZeroReadProfile
} else {
CodePushingIfArmProfile
}
}
///|
fn gen_valid_code_pushing_if_arm_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::local_get(LocalIdx::new(1U)), Instruction::drop()],
Some([Instruction::nop()]),
),
]
}
///|
fn gen_valid_code_pushing_after_if_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(3)),
Instruction::i32_const(I32(4)),
Instruction::i32_add(),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::nop()],
Some([Instruction::nop()]),
),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_code_pushing_dropped_if_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(1))],
Some([Instruction::i32_const(I32(2))]),
),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_br_if_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
]),
),
]
}
///|
fn gen_valid_code_pushing_br_on_null_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_on_null(LabelIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]),
),
]
}
///|
fn gen_valid_code_pushing_br_on_non_null_body() -> Array[Instruction] {
let extern_heap = HeapType::abs(AbsHeapType::extern_())
[
Instruction::block(
BlockType::val_type(ValType::externref()),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_on_non_null(LabelIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::ref_null(extern_heap),
]),
),
]
}
///|
fn gen_valid_code_pushing_br_on_non_null_prefix_body() -> Array[Instruction] {
let extern_heap = HeapType::abs(AbsHeapType::extern_())
[
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::i32_const(I32(42)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_on_non_null(LabelIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::i32_const(I32(13)),
Instruction::ref_null(extern_heap),
]),
),
Instruction::drop(),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_br_on_cast_body() -> Array[Instruction] {
let any_heap = HeapType::abs(AbsHeapType::any())
let i31_heap = HeapType::abs(AbsHeapType::i31())
[
Instruction::block(
BlockType::val_type(ValType::i31ref_nullable()),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_on_cast(
LabelIdx::new(0U),
true,
any_heap,
true,
i31_heap,
),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::ref_null(i31_heap),
]),
),
]
}
///|
fn gen_valid_code_pushing_br_on_cast_fail_body() -> Array[Instruction] {
let any_heap = HeapType::abs(AbsHeapType::any())
let i31_heap = HeapType::abs(AbsHeapType::i31())
[
Instruction::block(
BlockType::val_type(ValType::anyref()),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_on_cast_fail(
LabelIdx::new(0U),
true,
any_heap,
true,
i31_heap,
),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::ref_null(any_heap),
]),
),
]
}
///|
fn gen_valid_code_pushing_br_if_value_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::i32_const(I32(42)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
]),
),
]
}
///|
fn gen_valid_code_pushing_multi_set_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::nop()],
Some([Instruction::nop()]),
),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_multi_set_dropped_if_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(1))],
Some([Instruction::i32_const(I32(2))]),
),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_multi_set_nop_window_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::nop(),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::nop()],
Some([Instruction::nop()]),
),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_loop_br_if_body() -> Array[Instruction] {
[
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]),
),
]
}
///|
fn gen_valid_code_pushing_multi_set_drop_window_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(99)),
Instruction::drop(),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::nop()],
Some([Instruction::nop()]),
),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_multi_set_local_get_window_body() -> Array[
Instruction,
] {
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::if_(
BlockType::void_(),
[Instruction::nop()],
Some([Instruction::nop()]),
),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(3U)),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_multi_set_global_get_window_body() -> Array[
Instruction,
] {
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::drop(),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::nop()],
Some([Instruction::nop()]),
),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_multi_set_local_copy_body() -> Array[Instruction] {
[
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(4U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[Instruction::nop()],
Some([Instruction::nop()]),
),
Instruction::local_get(LocalIdx::new(3U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(4U)),
Instruction::drop(),
]
}
///|
fn gen_valid_code_pushing_multi_set_br_if_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
]),
),
]
}
///|
fn gen_valid_code_pushing_zero_read_profile_module() -> Module {
let func_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [])),
)
let make_func = fn(body : Array[Instruction]) {
Func::new(Locals::from_types([ValType::i32()]), Expr::new(body))
}
Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U), TypeIdx::new(0U)]),
)
.with_code_sec(
CodeSec::new([
make_func([
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(BlockType::void_(), [Instruction::nop()], None),
Instruction::i32_const(I32(0)),
Instruction::drop(),
]),
make_func([
Instruction::i32_const(I32(8)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(1))],
Some([Instruction::i32_const(I32(2))]),
),
Instruction::drop(),
Instruction::i32_const(I32(0)),
Instruction::drop(),
]),
make_func([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::drop(),
]),
),
]),
]),
)
}
///|
fn gen_valid_code_pushing_profile_module(config : GenValidConfig) -> Module {
let kind = gen_valid_code_pushing_profile_kind(config)
if kind == CodePushingZeroReadProfile {
return gen_valid_code_pushing_zero_read_profile_module()
}
let result_type = if kind == CodePushingAfterIfProfile ||
kind == CodePushingBrIfValueProfile {
[ValType::i32()]
} else if kind == CodePushingBrOnNonNullProfile {
[ValType::externref()]
} else if kind == CodePushingBrOnCastProfile {
[ValType::i31ref_nullable()]
} else if kind == CodePushingBrOnCastFailProfile {
[ValType::anyref()]
} else {
[]
}
let body = match kind {
CodePushingAfterIfProfile => gen_valid_code_pushing_after_if_body()
CodePushingDroppedIfProfile => gen_valid_code_pushing_dropped_if_body()
CodePushingBrIfProfile => gen_valid_code_pushing_br_if_body()
CodePushingBrOnNullProfile => gen_valid_code_pushing_br_on_null_body()
CodePushingBrOnNonNullProfile =>
gen_valid_code_pushing_br_on_non_null_body()
CodePushingBrOnNonNullPrefixProfile =>
gen_valid_code_pushing_br_on_non_null_prefix_body()
CodePushingBrOnCastProfile => gen_valid_code_pushing_br_on_cast_body()
CodePushingBrOnCastFailProfile =>
gen_valid_code_pushing_br_on_cast_fail_body()
CodePushingBrIfValueProfile => gen_valid_code_pushing_br_if_value_body()
CodePushingMultiSetProfile => gen_valid_code_pushing_multi_set_body()
CodePushingMultiSetDroppedIfProfile =>
gen_valid_code_pushing_multi_set_dropped_if_body()
CodePushingMultiSetBrIfProfile =>
gen_valid_code_pushing_multi_set_br_if_body()
CodePushingMultiSetLocalCopyProfile =>
gen_valid_code_pushing_multi_set_local_copy_body()
CodePushingMultiSetNopWindowProfile =>
gen_valid_code_pushing_multi_set_nop_window_body()
CodePushingLoopBrIfProfile => gen_valid_code_pushing_loop_br_if_body()
CodePushingMultiSetDropWindowProfile =>
gen_valid_code_pushing_multi_set_drop_window_body()
CodePushingMultiSetLocalGetWindowProfile =>
gen_valid_code_pushing_multi_set_local_get_window_body()
CodePushingMultiSetGlobalGetWindowProfile =>
gen_valid_code_pushing_multi_set_global_get_window_body()
_ => gen_valid_code_pushing_if_arm_body()
}
let params = if kind == CodePushingMultiSetLocalCopyProfile {
[ValType::i32(), ValType::i32(), ValType::i32()]
} else if kind == CodePushingMultiSetLocalGetWindowProfile {
[ValType::i32(), ValType::i32()]
} else if kind == CodePushingBrOnNullProfile ||
kind == CodePushingBrOnNonNullProfile ||
kind == CodePushingBrOnNonNullPrefixProfile {
[ValType::externref()]
} else if kind == CodePushingBrOnCastProfile ||
kind == CodePushingBrOnCastFailProfile {
[ValType::anyref()]
} else {
[ValType::i32()]
}
let func_type = RecType::new(
SubType::comp_type(CompType::func(params, result_type)),
)
let block_type = RecType::new(
SubType::comp_type(
CompType::func([], [ValType::i32(), ValType::externref()]),
),
)
let type_sec = if kind == CodePushingBrOnNonNullPrefixProfile {
TypeSec::new([func_type, block_type])
} else {
TypeSec::new([func_type])
}
let mod = Module::new()
.with_type_sec(type_sec)
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(
if kind == CodePushingBrIfValueProfile ||
kind == CodePushingMultiSetProfile ||
kind == CodePushingMultiSetDroppedIfProfile ||
kind == CodePushingMultiSetBrIfProfile ||
kind == CodePushingBrOnNullProfile ||
kind == CodePushingBrOnNonNullProfile ||
kind == CodePushingBrOnNonNullPrefixProfile ||
kind == CodePushingBrOnCastProfile ||
kind == CodePushingBrOnCastFailProfile ||
kind == CodePushingMultiSetLocalCopyProfile ||
kind == CodePushingMultiSetNopWindowProfile ||
kind == CodePushingLoopBrIfProfile ||
kind == CodePushingMultiSetDropWindowProfile ||
kind == CodePushingMultiSetGlobalGetWindowProfile {
[ValType::i32(), ValType::i32()]
} else if kind == CodePushingMultiSetLocalGetWindowProfile {
[ValType::i32(), ValType::i32()]
} else {
[ValType::i32()]
},
),
Expr::new(body),
),
]),
)
if kind == CodePushingMultiSetGlobalGetWindowProfile {
mod.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), false),
Expr::new([Instruction::i32_const(I32(42))]),
),
]),
)
} else {
mod
}
}
///|
fn gen_valid_remove_unused_brs_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
for
profile in [
RemoveUnusedBrsConstantBrIfProfile,
RemoveUnusedBrsSingleTargetBrTableProfile,
RemoveUnusedBrsMultiFunctionProfile,
RemoveUnusedBrsResultRefinalizeProfile,
RemoveUnusedBrsMultivalueDropProfile,
RemoveUnusedBrsWrapperCleanupProfile,
RemoveUnusedBrsSelectifyProfile,
RemoveUnusedBrsTailFlowProfile,
RemoveUnusedBrsOneArmIfProfile,
RemoveUnusedBrsLoopProfile,
RemoveUnusedBrsSinkBlocksProfile,
RemoveUnusedBrsEhProfile,
RemoveUnusedBrsJumpThreadProfile,
RemoveUnusedBrsTablifyProfile,
RemoveUnusedBrsOptimizeSetIfProfile,
RemoveUnusedBrsRestructureIfProfile,
RemoveUnusedBrsAdjacentBranchProfile,
RemoveUnusedBrsWinBoundaryProfile,
] {
if config == GenValidConfig::for_profile(profile) {
return profile
}
}
RemoveUnusedBrsConstantBrIfProfile
}
///|
fn gen_valid_remove_unused_brs_pair_type() -> RecType {
RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32(), ValType::i64()])),
)
}
///|
fn gen_valid_remove_unused_brs_profile_body(
ctx : GenValidContext,
kind : GenValidProfile,
) -> Array[Instruction] {
let out : Array[Instruction] = []
match kind {
RemoveUnusedBrsConstantBrIfProfile =>
for
vt in [
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
ValType::v128(),
ValType::funcref(),
] {
gen_valid_append_remove_unused_brs_br_if_case(out, ctx, vt)
}
RemoveUnusedBrsSingleTargetBrTableProfile =>
for
vt in [
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
ValType::v128(),
ValType::funcref(),
] {
gen_valid_append_remove_unused_brs_br_table_case(out, ctx, vt)
}
RemoveUnusedBrsResultRefinalizeProfile => {
out.push(Instruction::i32_const(I32(1)))
out.push(
Instruction::if_(
BlockType::val_type(ValType::anyref()),
[Instruction::i32_const(I32(3)), Instruction::ref_i31()],
Some([Instruction::i32_const(I32(5)), Instruction::ref_i31()]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(ValType::anyref()),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::ref_i31(),
Instruction::br(LabelIdx::new(0U)),
Instruction::i32_const(I32(9)),
Instruction::ref_i31(),
]),
),
)
out.push(Instruction::drop())
}
RemoveUnusedBrsMultivalueDropProfile => {
out.push(
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(11)),
Instruction::i64_const(I64(13L)),
]),
),
)
out.push(Instruction::drop())
out.push(Instruction::drop())
}
RemoveUnusedBrsWrapperCleanupProfile => {
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::br(LabelIdx::new(0U))]),
),
)
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::i32_const(I32(17)),
Instruction::br(LabelIdx::new(0U)),
Instruction::unreachable_(),
]),
),
)
out.push(Instruction::drop())
out.push(
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(19)),
Instruction::br(LabelIdx::new(1U)),
Instruction::unreachable_(),
]),
),
Instruction::unreachable_(),
]),
),
)
out.push(Instruction::drop())
}
RemoveUnusedBrsSelectifyProfile => {
out.push(Instruction::i32_const(I32(1)))
out.push(
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(23))],
Some([Instruction::i32_const(I32(29))]),
),
)
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(0)))
out.push(
Instruction::if_(
BlockType::val_type(ValType::anyref()),
[Instruction::i32_const(I32(31)), Instruction::ref_i31()],
Some([Instruction::i32_const(I32(37)), Instruction::ref_i31()]),
),
)
out.push(Instruction::drop())
}
RemoveUnusedBrsTailFlowProfile => {
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::br(LabelIdx::new(0U))]),
),
)
out.push(Instruction::return_())
}
RemoveUnusedBrsOneArmIfProfile =>
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::br(LabelIdx::new(1U))],
None,
),
]),
),
)
RemoveUnusedBrsLoopProfile =>
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(1U)),
Instruction::br(LabelIdx::new(0U)),
]),
),
]),
),
)
RemoveUnusedBrsSinkBlocksProfile =>
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::local_get(LocalIdx::new(1U)),
Instruction::br_if(LabelIdx::new(1U)),
Instruction::nop(),
],
Some([Instruction::nop(), Instruction::nop()]),
),
]),
),
)
RemoveUnusedBrsEhProfile => ()
RemoveUnusedBrsJumpThreadProfile =>
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::br(LabelIdx::new(1U))]),
),
]),
),
)
RemoveUnusedBrsTablifyProfile => {
for value in [0, 1, 2] {
out.push(Instruction::local_get(LocalIdx::new(0U)))
out.push(Instruction::i32_const(I32(value)))
out.push(Instruction::i32_eq())
out.push(Instruction::br_if(LabelIdx::new(0U)))
}
let ladder = out.copy()
out.clear()
out.push(Instruction::block(BlockType::void_(), Expr::new(ladder)))
}
RemoveUnusedBrsOptimizeSetIfProfile => {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::local_set(LocalIdx::new(0U)))
out.push(Instruction::local_get(LocalIdx::new(1U)))
out.push(
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(7))],
Some([Instruction::local_get(LocalIdx::new(0U))]),
),
)
out.push(Instruction::local_set(LocalIdx::new(0U)))
}
RemoveUnusedBrsRestructureIfProfile =>
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::i32_const(I32(9)),
Instruction::drop(),
]),
),
)
RemoveUnusedBrsAdjacentBranchProfile =>
out.push(
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::br_if(LabelIdx::new(0U)),
Instruction::br(LabelIdx::new(0U)),
]),
),
)
RemoveUnusedBrsWinBoundaryProfile => {
out.push(Instruction::i32_const(I32(41)))
out.push(Instruction::local_tee(LocalIdx::new(0U)))
out.push(Instruction::drop())
}
_ => ()
}
out
}
///|
fn gen_valid_remove_unused_brs_profile_module(ctx : GenValidContext) -> Module {
let kind = gen_valid_remove_unused_brs_profile_kind(ctx.config)
let void_type = gen_valid_precompute_void_func_type()
let pair_type = gen_valid_remove_unused_brs_pair_type()
if kind == RemoveUnusedBrsEhProfile {
let tag_type = RecType::new(SubType::comp_type(CompType::func([], [])))
return Module::new()
.with_type_sec(TypeSec::new([tag_type, void_type]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(0U))]))
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::new(TagIdx::new(0U), LabelIdx::new(0U))],
Expr::new([Instruction::throw_(TagIdx::new(0U))]),
),
Instruction::unreachable_(),
]),
),
]),
),
]),
)
}
if kind == RemoveUnusedBrsMultiFunctionProfile {
let first_body = gen_valid_remove_unused_brs_profile_body(
ctx,
RemoveUnusedBrsConstantBrIfProfile,
)
let second_body : Array[Instruction] = [
Instruction::i64_const(I64(43L)),
Instruction::local_set(LocalIdx::new(0U)),
]
for
instr in gen_valid_remove_unused_brs_profile_body(
ctx,
RemoveUnusedBrsSingleTargetBrTableProfile,
) {
second_body.push(instr)
}
second_body.push(Instruction::i32_const(I32(47)))
second_body.push(Instruction::i64_const(I64(53L)))
return Module::new()
.with_type_sec(TypeSec::new([void_type, pair_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_code_sec(
CodeSec::new([
Func::new(Locals::new([]), Expr::new(first_body)),
Func::new(
Locals::from_types([ValType::i64()]),
Expr::new(second_body),
),
]),
)
}
let locals = if kind == RemoveUnusedBrsSinkBlocksProfile ||
kind == RemoveUnusedBrsOptimizeSetIfProfile {
Locals::from_types([ValType::i32(), ValType::i32()])
} else if kind == RemoveUnusedBrsWinBoundaryProfile ||
kind == RemoveUnusedBrsTablifyProfile ||
kind == RemoveUnusedBrsLoopProfile ||
kind == RemoveUnusedBrsRestructureIfProfile {
Locals::from_types([ValType::i32()])
} else {
Locals::new([])
}
Module::new()
.with_type_sec(TypeSec::new([void_type, pair_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
locals,
Expr::new(gen_valid_remove_unused_brs_profile_body(ctx, kind)),
),
]),
)
}
///|
fn gen_valid_tuple_optimization_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(TupleOptimizationCopyChainProfile) {
TupleOptimizationCopyChainProfile
} else if config == GenValidConfig::for_profile(TupleOptimizationTeeProfile) {
TupleOptimizationTeeProfile
} else {
TupleOptimizationSpillProfile
}
}
///|
fn gen_valid_tuple_optimization_multivalue_type() -> RecType {
RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32(), ValType::i64()])),
)
}
///|
fn gen_valid_tuple_optimization_spill_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::i64_const(I64(9L)),
]),
),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
]
}
///|
fn gen_valid_tuple_optimization_copy_chain_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(11)),
Instruction::i64_const(I64(13L)),
]),
),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(1U)),
]),
),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(3U)),
Instruction::drop(),
]
}
///|
fn gen_valid_tuple_optimization_tee_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::type_idx(TypeIdx::new(1U)),
Expr::new([
Instruction::i32_const(I32(17)),
Instruction::i64_const(I64(19L)),
]),
),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
]
}
///|
fn gen_valid_tuple_optimization_profile_module(
config : GenValidConfig,
) -> Module {
let kind = gen_valid_tuple_optimization_profile_kind(config)
let body = match kind {
TupleOptimizationCopyChainProfile =>
gen_valid_tuple_optimization_copy_chain_body()
TupleOptimizationTeeProfile => gen_valid_tuple_optimization_tee_body()
_ => gen_valid_tuple_optimization_spill_body()
}
// Retain the original carrier/drop triggers, then expose both final lanes.
// Exportless void fixtures only tested instantiation in the runtime oracle.
let first_local = if kind == TupleOptimizationCopyChainProfile {
2U
} else {
0U
}
body.append([
Instruction::local_get(LocalIdx::new(first_local)),
Instruction::local_get(LocalIdx::new(first_local + 1U)),
])
let func_type = gen_valid_tuple_optimization_multivalue_type()
Module::new()
.with_type_sec(
TypeSec::new([func_type, gen_valid_tuple_optimization_multivalue_type()]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(
if kind == TupleOptimizationCopyChainProfile {
[ValType::i32(), ValType::i64(), ValType::i32(), ValType::i64()]
} else {
[ValType::i32(), ValType::i64()]
},
),
Expr::new(body),
),
]),
)
}
///|
fn gen_valid_oi_trigger_profile_case_modulus(
profile : GenValidProfile,
) -> Int32 {
match profile {
PassOiMemoryBulkProfile => 49
PassOiGcAggregateProfile => 15
PassOiTupleProfile => 21
PassOiLocalFactsProfile => 15
PassOiBooleanSelectProfile => 4
PassOiCallRefProfile => 10
PassOiDescriptorGcProfile => 4
_ => 3
}
}
///|
fn gen_valid_oi_memory_bulk_case_for_seed(seed : UInt64) -> Int32 {
match seed {
0x5eedUL => 1
0x5eeeUL => 2
0x5eefUL => 3
0x5ef0UL => 4
0x5ef1UL => 5
0x5ef2UL => 0
0x5ef3UL => 6
0x5ef4UL => 7
0x5ef5UL => 8
0x5ef6UL => 9
0x5ef7UL => 10
0x5ef8UL => 11
0x5ef9UL => 12
0x5efaUL => 13
0x5efbUL => 14
0x5efcUL => 15
0x5efdUL => 16
0x5efeUL => 17
0x5effUL => 18
0x5f00UL => 19
0x5f01UL => 20
0x5f02UL => 21
0x5f03UL => 22
0x5f04UL => 23
0x5f05UL => 24
0x5f06UL => 25
0x5f07UL => 26
0x5f08UL => 27
0x5f09UL => 28
0x5f0aUL => 29
0x5f0bUL => 30
0x5f0cUL => 31
0x5f0dUL => 32
0x5f0eUL => 33
0x5f0fUL => 34
0x5f10UL => 35
0x5f11UL => 36
0x5f12UL => 37
0x5f13UL => 38
0x5f14UL => 39
0x5f15UL => 40
0x5f16UL => 41
0x5f17UL => 42
0x5f18UL => 43
0x5f19UL => 44
0x5f1aUL => 45
0x5f1bUL => 46
0x5f1cUL => 47
0x5f1dUL => 48
_ =>
match (seed % 49UL).to_int() {
0 => 9
1 => 10
2 => 11
3 => 12
4 => 13
5 => 14
6 => 15
7 => 16
8 => 17
9 => 18
10 => 19
11 => 20
12 => 21
13 => 22
14 => 23
15 => 24
16 => 25
17 => 26
18 => 27
19 => 28
20 => 29
21 => 30
22 => 31
23 => 32
24 => 33
25 => 34
26 => 35
27 => 36
28 => 37
29 => 38
30 => 39
31 => 40
32 => 41
33 => 42
34 => 43
35 => 44
36 => 45
37 => 46
38 => 47
39 => 48
40 => 1
41 => 2
42 => 3
43 => 4
44 => 5
45 => 0
46 => 6
47 => 7
_ => 8
}
}
}
///|
fn gen_valid_oi_tuple_case_for_seed(seed : UInt64) -> Int32 {
match seed {
0x5eedUL => 1
0x5eeeUL => 2
0x5eefUL => 0
0x5ef0UL => 3
0x5ef1UL => 4
0x5ef2UL => 5
0x5ef3UL => 6
0x5ef4UL => 7
0x5ef5UL => 8
0x5ef6UL => 9
0x5ef7UL => 10
0x5ef8UL => 11
0x5ef9UL => 12
0x5efaUL => 13
0x5efbUL => 14
0x5efcUL => 15
0x5efdUL => 13
0x5efeUL => 16
0x5effUL => 17
0x6000UL => 18
0x6001UL => 19
0x6002UL => 20
0x6003UL => 21
_ => (seed % 22UL).to_int()
}
}
///|
fn gen_valid_oi_local_facts_case_for_seed(seed : UInt64) -> Int32 {
match seed {
0x5eedUL => 1
0x5eeeUL => 2
0x5eefUL => 0
0x5ef0UL => 3
0x5ef1UL => 4
0x5ef2UL => 5
0x5ef3UL => 6
0x5ef4UL => 7
0x5ef5UL => 8
0x5ef6UL => 9
0x5ef7UL => 10
0x5ef8UL => 11
0x5ef9UL => 12
0x5efaUL => 13
0x5efbUL => 14
_ => (seed % 15UL).to_int()
}
}
///|
fn gen_valid_oi_boolean_select_case_for_seed(seed : UInt64) -> Int32 {
match seed {
0x5eedUL => 0
0x5eeeUL => 1
0x5eefUL => 2
0x5ef0UL => 3
_ => (seed % 4UL).to_int()
}
}
///|
fn gen_valid_oi_call_ref_case_for_seed(seed : UInt64) -> Int32 {
match seed {
0x5eedUL => 1
0x5eeeUL => 2
0x5eefUL => 3
0x5ef0UL => 0
0x5ef1UL => 4
0x5ef2UL => 5
0x5ef3UL => 6
0x5ef4UL => 7
0x5ef5UL => 8
0x5ef6UL => 9
_ => (seed % 10UL).to_int()
}
}
///|
fn gen_valid_oi_gc_aggregate_case_for_seed(seed : UInt64) -> Int32 {
match seed {
0x5eedUL => 0
0x5eeeUL => 1
0x5eefUL => 2
0x5ef0UL => 3
0x5ef1UL => 4
0x5ef2UL => 5
0x5ef3UL => 6
0x5ef4UL => 7
0x5ef5UL => 8
0x5ef6UL => 9
0x5ef7UL => 10
0x5ef8UL => 11
0x5ef9UL => 12
0x5efaUL => 13
0x5efbUL => 14
_ => (seed % 15UL).to_int()
}
}
///|
fn gen_valid_oi_trigger_profile_case_for_profile_seed(
profile : GenValidProfile,
seed : UInt64,
) -> Int32 {
match profile {
PassOiMemoryBulkProfile => gen_valid_oi_memory_bulk_case_for_seed(seed)
PassOiTupleProfile => gen_valid_oi_tuple_case_for_seed(seed)
PassOiLocalFactsProfile => gen_valid_oi_local_facts_case_for_seed(seed)
PassOiBooleanSelectProfile =>
gen_valid_oi_boolean_select_case_for_seed(seed)
PassOiCallRefProfile => gen_valid_oi_call_ref_case_for_seed(seed)
PassOiGcAggregateProfile => gen_valid_oi_gc_aggregate_case_for_seed(seed)
_ =>
(seed % gen_valid_oi_trigger_profile_case_modulus(profile).to_uint64()).to_int()
}
}
///|
fn gen_valid_oi_trigger_profile_for_config(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(PassOiMemoryBulkProfile) {
PassOiMemoryBulkProfile
} else if config == GenValidConfig::for_profile(PassOiLocalFactsProfile) {
PassOiLocalFactsProfile
} else if config == GenValidConfig::for_profile(PassOiBooleanSelectProfile) {
PassOiBooleanSelectProfile
} else if config == GenValidConfig::for_profile(PassOiCallRefProfile) {
PassOiCallRefProfile
} else if config == GenValidConfig::for_profile(PassOiRefGcProfile) {
PassOiRefGcProfile
} else if config == GenValidConfig::for_profile(PassOiGcAggregateProfile) {
PassOiGcAggregateProfile
} else if config == GenValidConfig::for_profile(PassOiDescriptorGcProfile) {
PassOiDescriptorGcProfile
} else if config == GenValidConfig::for_profile(PassOiTupleProfile) {
PassOiTupleProfile
} else {
PassOiDefaultScalarProfile
}
}
///|
fn gen_valid_oi_trigger_profile_case(ctx : GenValidContext) -> Int32 {
let profile = gen_valid_oi_trigger_profile_for_config(ctx.config)
match profile {
PassOiMemoryBulkProfile
| PassOiTupleProfile
| PassOiLocalFactsProfile
| PassOiBooleanSelectProfile
| PassOiCallRefProfile
| PassOiGcAggregateProfile =>
gen_valid_oi_trigger_profile_case_for_profile_seed(profile, ctx.root_seed)
_ =>
if ctx.use_named_streams {
gen_valid_oi_trigger_profile_case_for_profile_seed(
profile,
ctx.root_seed,
)
} else {
let modulus = gen_valid_oi_trigger_profile_case_modulus(profile)
ctx.random_int_from(BodyStream, modulus)
}
}
}
///|
pub fn gen_valid_oi_trigger_profile_case_for_seed(seed : UInt64) -> Int32 {
(seed % 3UL).to_int()
}
///|
pub fn gen_valid_oi_trigger_profile_case_label(
profile : GenValidProfile,
seed : UInt64,
) -> String? {
let case = gen_valid_oi_trigger_profile_case_for_profile_seed(profile, seed)
match profile {
PassOiDefaultScalarProfile =>
match case {
1 => Some("oi-default-scalar:local-carried-add-zero")
2 => Some("oi-default-scalar:local-tee-commuted-add-zero")
_ => Some("oi-default-scalar:direct")
}
PassOiLocalFactsProfile =>
match case {
1 => Some("oi-local-facts:local-tee-add-zero")
2 => Some("oi-local-facts:local-carried-mask")
3 => Some("oi-local-facts:existing-producer-sign-extension")
4 => Some("oi-local-facts:effectful-existing-producer-sign-extension")
5 => Some("oi-local-facts:trapping-existing-producer-sign-extension")
6 => Some("oi-local-facts:localtee-existing-producer-sign-extension")
7 => Some("oi-local-facts:wide-local-carried-mask")
8 =>
Some("oi-local-facts:local-carried-existing-producer-sign-extension")
9 =>
Some(
"oi-local-facts:effectful-local-carried-existing-producer-sign-extension",
)
10 => Some("oi-local-facts:wrap-extend-mask")
11 => Some("oi-local-facts:shifted-mask")
12 => Some("oi-local-facts:wide-shifted-mask")
13 => Some("oi-local-facts:select-produced-mask")
14 => Some("oi-local-facts:block-produced-mask")
_ => Some("oi-local-facts:direct-sign-extension")
}
PassOiBooleanSelectProfile =>
match case {
1 => Some("oi-boolean-select:effectful-identical-select")
2 => Some("oi-boolean-select:trapping-dead-if-arm")
3 => Some("oi-boolean-select:value-if-drop-shell")
_ => Some("oi-boolean-select:direct-if-select-shell")
}
PassOiCallRefProfile =>
match case {
1 => Some("oi-call-ref:local-carried-target")
2 => Some("oi-call-ref:block-produced-target")
3 => Some("oi-call-ref:return-call-ref-target")
4 => Some("oi-call-ref:table-get-target")
5 => Some("oi-call-ref:return-table-get-target")
6 => Some("oi-call-ref:argument-direct-target")
7 => Some("oi-call-ref:argument-local-target")
8 => Some("oi-call-ref:argument-multivalue-target")
9 => Some("oi-call-ref:argument-select-target")
_ => Some("oi-call-ref:direct-target-wrapper")
}
PassOiRefGcProfile =>
match case {
1 => Some("oi-ref-gc:local-carried-null-test-cast")
2 => Some("oi-ref-gc:branch-cast-boundaries")
_ => Some("oi-ref-gc:direct-null-test-cast-eq")
}
PassOiGcAggregateProfile =>
match case {
0 => Some("oi-gc-aggregate:struct-get-new-pure")
1 => Some("oi-gc-aggregate:struct-get-new-effectful-sibling")
2 => Some("oi-gc-aggregate:array-get-new-fixed-pure")
3 => Some("oi-gc-aggregate:array-get-new-fixed-effectful-sibling")
4 => Some("oi-gc-aggregate:array-set-new-fixed-effectful-value")
5 => Some("oi-gc-aggregate:array-set-new-fixed-effectful-oob")
6 => Some("oi-gc-aggregate:array-new-len-pure")
7 => Some("oi-gc-aggregate:array-new-len-effectful")
8 => Some("oi-gc-aggregate:array-get-new-effectful-repeated")
9 => Some("oi-gc-aggregate:array-get-new-effectful-oob")
10 => Some("oi-gc-aggregate:array-set-new-effectful-repeated")
11 => Some("oi-gc-aggregate:array-set-new-effectful-repeated-and-value")
12 => Some("oi-gc-aggregate:dynamic-index-boundary")
13 => Some("oi-gc-aggregate:dynamic-length-boundary")
_ => Some("oi-gc-aggregate:negative-huge-length-boundary")
}
PassOiDescriptorGcProfile =>
match case {
0 => Some("oi-descriptor-gc:trapping-null-desc-cast")
2 => Some("oi-descriptor-gc:null-desc-cast")
3 => Some("oi-descriptor-gc:effectful-null-desc-cast")
_ => Some("oi-descriptor-gc:desc-producer-test-cast")
}
PassOiTupleProfile =>
match case {
1 => Some("oi-tuple:selected-lane-all-results")
2 => Some("oi-tuple:local-carried-selected-lane")
3 => Some("oi-tuple:call-produced-selected-lane")
4 => Some("oi-tuple:effectful-sibling-selected-lane")
5 => Some("oi-tuple:trapping-sibling-selected-lane")
6 => Some("oi-tuple:localtee-produced-selected-lane")
7 => Some("oi-tuple:select-produced-selected-lane")
8 => Some("oi-tuple:selected-trapping-lane")
9 => Some("oi-tuple:selected-effectful-lane")
10 => Some("oi-tuple:effectful-select-operand-selected-lane")
11 => Some("oi-tuple:trapping-select-operand-selected-lane")
12 => Some("oi-tuple:multi-selected-effectful-lanes")
13 => Some("oi-tuple:randomized-existing-effect-trap-lanes")
14 => Some("oi-tuple:runtime-selected-lane")
15 => Some("oi-tuple:runtime-effectful-selected-lane")
16 => Some("oi-tuple:scratch-localized-selected-lane")
17 => Some("oi-tuple:effectful-scratch-localized-selected-lane")
18 => Some("oi-tuple:runtime-all-results")
19 => Some("oi-tuple:runtime-effectful-scratch-localized-selected-lane")
20 => Some("oi-tuple:runtime-multi-selected-effectful-lanes")
21 =>
Some(
"oi-tuple:runtime-mixed-effect-trap-scratch-localized-selected-lane",
)
_ => Some("oi-tuple:direct-selected-lane")
}
PassOiMemoryBulkProfile =>
match case {
1 => Some("oi-memory-bulk:memory64-dynamic-bulk")
2 => Some("oi-memory-bulk:live-effect-trap-boundaries")
3 => Some("oi-memory-bulk:existing-producer-wrapped-bulk")
4 => Some("oi-memory-bulk:store-mask-boundaries")
5 => Some("oi-memory-bulk:dynamic-i32-bulk-operands")
6 => Some("oi-memory-bulk:multi-memory-bulk")
7 => Some("oi-memory-bulk:random-address-copy-read")
8 => Some("oi-memory-bulk:multi-memory-random-address-copy-read")
9 => Some("oi-memory-bulk:cross-memory-random-address-copy-read")
10 =>
Some("oi-memory-bulk:memory64-cross-memory-random-address-copy-read")
11 => Some("oi-memory-bulk:cross-memory-restore-copy-read")
12 => Some("oi-memory-bulk:memory64-cross-memory-restore-copy-read")
13 => Some("oi-memory-bulk:runtime-restore-copy-read")
14 => Some("oi-memory-bulk:shared-wait-notify")
15 => Some("oi-memory-bulk:runtime-fill-restore-read")
16 => Some("oi-memory-bulk:memory64-fill-restore-read")
17 => Some("oi-memory-bulk:multi-memory-fill-restore-read")
18 => Some("oi-memory-bulk:memory64-multi-memory-fill-restore-read")
19 => Some("oi-memory-bulk:runtime-call-fill-restore-read")
20 => Some("oi-memory-bulk:runtime-call-restore-copy-read")
21 => Some("oi-memory-bulk:runtime-localtee-restore-copy-read")
22 => Some("oi-memory-bulk:runtime-select-restore-copy-read")
23 => Some("oi-memory-bulk:runtime-select-fill-restore-read")
24 => Some("oi-memory-bulk:shared-atomic-xchg-restore")
25 => Some("oi-memory-bulk:runtime-store8-mask-restore-read")
26 => Some("oi-memory-bulk:shared-atomic-random-xchg-restore")
27 => Some("oi-memory-bulk:shared-atomic-random-add-restore")
28 => Some("oi-memory-bulk:shared-atomic-random-cmpxchg-restore")
29 => Some("oi-memory-bulk:shared-atomic-random-sub-restore")
30 => Some("oi-memory-bulk:shared-atomic-random-xor-restore")
31 => Some("oi-memory-bulk:shared-atomic-random-or-restore")
32 => Some("oi-memory-bulk:shared-atomic-random-and-restore")
33 => Some("oi-memory-bulk:shared-atomic-localtee-add-restore")
34 => Some("oi-memory-bulk:shared-atomic-call-add-restore")
35 => Some("oi-memory-bulk:shared-atomic-select-add-restore")
36 => Some("oi-memory-bulk:shared-atomic-select-xchg-restore")
37 => Some("oi-memory-bulk:shared-atomic-select-cmpxchg-restore")
38 => Some("oi-memory-bulk:shared-atomic-select-sub-restore")
39 => Some("oi-memory-bulk:shared-atomic-select-xor-restore")
40 => Some("oi-memory-bulk:shared-atomic-select-or-restore")
41 => Some("oi-memory-bulk:shared-atomic-select-and-restore")
42 => Some("oi-memory-bulk:shared-atomic-localtee-xchg-restore")
43 => Some("oi-memory-bulk:shared-atomic-localtee-sub-restore")
44 => Some("oi-memory-bulk:shared-atomic-localtee-xor-restore")
45 => Some("oi-memory-bulk:shared-atomic-localtee-or-restore")
46 => Some("oi-memory-bulk:shared-atomic-localtee-and-restore")
47 => Some("oi-memory-bulk:shared-atomic-localtee-cmpxchg-restore")
48 =>
Some(
"oi-memory-bulk:memory64-multi-memory-localtee-fill-restore-read",
)
_ => Some("oi-memory-bulk:direct-tiny-bulk")
}
_ => None
}
}
///|
fn gen_valid_oi_default_scalar_profile_body(case : Int32) -> Array[Instruction] {
let direct = [
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
Instruction::drop(),
Instruction::i32_const(I32(1)),
Instruction::i32_eqz(),
Instruction::i32_eqz(),
Instruction::drop(),
Instruction::i64_const(I64(0L)),
Instruction::i64_eqz(),
Instruction::drop(),
Instruction::i32_const(I32(0x7f)),
Instruction::i32_extend8s(),
Instruction::drop(),
Instruction::i64_const(I64(0x7fffffffL)),
Instruction::i64_extend32s(),
Instruction::drop(),
Instruction::i32_const(I32(4)),
Instruction::i32_const(I32(2)),
Instruction::i32_shl(),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(-2147483648)),
Instruction::i32_div_u(),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(-2147483648)),
Instruction::i32_mul(),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(-2147483648)),
Instruction::i32_rem_u(),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_or(),
Instruction::drop(),
]
match case {
1 => {
let out = [
Instruction::i32_const(I32(11)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
Instruction::drop(),
]
out.append(direct)
out
}
2 => {
let out = [
Instruction::i32_const(I32(13)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
Instruction::drop(),
Instruction::i32_const(I32(0)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_add(),
Instruction::drop(),
]
out.append(direct)
out
}
_ => direct
}
}
///|
fn gen_valid_oi_local_facts_profile_body(case : Int32) -> Array[Instruction] {
let direct_sign_ext = [
Instruction::i32_const(I32(0x7f)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_extend8s(),
Instruction::drop(),
Instruction::i64_const(I64(0x7fffffffL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_extend32s(),
Instruction::drop(),
]
match case {
1 => {
let out = [
Instruction::i32_const(I32(8)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
Instruction::drop(),
]
out.append(direct_sign_ext)
out
}
2 => {
let out : Array[Instruction] = []
out.append(direct_sign_ext)
out.append([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(1)),
Instruction::i32_and(),
Instruction::drop(),
])
out
}
7 => {
let out : Array[Instruction] = []
out.append(direct_sign_ext)
out.append([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0xff)),
Instruction::i32_and(),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_const(I64(0xffffL)),
Instruction::i64_and(),
Instruction::drop(),
])
out
}
10 => {
let out : Array[Instruction] = []
out.append(direct_sign_ext)
out.append([
Instruction::i64_const(I64(0xffL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_wrap_i64(),
Instruction::i32_const(I32(0xff)),
Instruction::i32_and(),
Instruction::drop(),
Instruction::i32_const(I32(0xff)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::i64_const(I64(0xffL)),
Instruction::i64_and(),
Instruction::drop(),
])
out
}
11 => {
let out : Array[Instruction] = []
out.append(direct_sign_ext)
out.append([
Instruction::i32_const(I32(0xff00)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(8)),
Instruction::i32_shr_u(),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0xff)),
Instruction::i32_and(),
Instruction::drop(),
Instruction::i64_const(I64(0xffff0000L)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_const(I64(16L)),
Instruction::i64_shr_u(),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_const(I64(0xffffL)),
Instruction::i64_and(),
Instruction::drop(),
])
out
}
12 => {
let out : Array[Instruction] = []
out.append(direct_sign_ext)
out.append([
Instruction::i32_const(I32(0x7f0000)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(16)),
Instruction::i32_shr_u(),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0x7f)),
Instruction::i32_and(),
Instruction::drop(),
Instruction::i64_const(I64(0x7fffffff0000L)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_const(I64(16L)),
Instruction::i64_shr_u(),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_const(I64(0x7fffffffL)),
Instruction::i64_and(),
Instruction::drop(),
])
out
}
13 => {
let out : Array[Instruction] = []
out.append(direct_sign_ext)
out.append([
Instruction::i32_const(I32(0xff00)),
Instruction::i32_const(I32(0xff)),
Instruction::i32_const(I32(0)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0xff)),
Instruction::i32_and(),
Instruction::drop(),
Instruction::i64_const(I64(0xffff0000L)),
Instruction::i64_const(I64(0xffffL)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i64()])),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_const(I64(0xffffL)),
Instruction::i64_and(),
Instruction::drop(),
])
out
}
14 => {
let out : Array[Instruction] = []
out.append(direct_sign_ext)
out.append([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::i32_const(I32(0xff))]),
),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0xff)),
Instruction::i32_and(),
Instruction::drop(),
Instruction::block(
BlockType::val_type(ValType::i64()),
Expr::new([Instruction::i64_const(I64(0xffffL))]),
),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_const(I64(0xffffL)),
Instruction::i64_and(),
Instruction::drop(),
])
out
}
_ => direct_sign_ext
}
}
///|
fn gen_valid_oi_local_facts_existing_producer_module() -> Module {
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
gen_valid_oi_local_facts_existing_producer_module_from_helpers(
i32_func_type,
i64_func_type,
Expr::new([Instruction::i32_const(I32(0x7f))]),
Expr::new([Instruction::i64_const(I64(0x7fffffffL))]),
None,
)
}
///|
fn gen_valid_oi_local_facts_effectful_existing_producer_module() -> Module {
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
gen_valid_oi_local_facts_existing_producer_module_from_helpers(
i32_func_type,
i64_func_type,
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(0x7f)),
]),
Expr::new([
Instruction::i32_const(I32(2)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i64_const(I64(0x7fffffffL)),
]),
Some(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
),
)
}
///|
fn gen_valid_oi_local_facts_trapping_existing_producer_module() -> Module {
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
gen_valid_oi_local_facts_existing_producer_module_from_helpers(
i32_func_type,
i64_func_type,
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::i32_div_s(),
]),
Expr::new([
Instruction::i64_const(I64(1L)),
Instruction::i64_const(I64(0L)),
Instruction::i64_div_s(),
]),
None,
)
}
///|
fn gen_valid_oi_local_facts_localtee_existing_producer_module() -> Module {
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let mod = Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_precompute_void_func_type(),
i32_func_type,
i64_func_type,
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(2U)]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::i32_extend8s(),
Instruction::drop(),
Instruction::call(FuncIdx::new(2U)),
Instruction::local_tee(LocalIdx::new(1U)),
Instruction::i64_extend32s(),
Instruction::drop(),
]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(0x7f))]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::i64_const(I64(0x7fffffffL))]),
),
]),
)
mod
}
///|
fn gen_valid_oi_local_facts_local_carried_existing_producer_module() -> Module {
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
gen_valid_oi_local_facts_local_carried_existing_producer_module_from_helpers(
i32_func_type,
i64_func_type,
Expr::new([Instruction::i32_const(I32(0x7f))]),
Expr::new([Instruction::i64_const(I64(0x7fffffffL))]),
None,
)
}
///|
fn gen_valid_oi_local_facts_effectful_local_carried_existing_producer_module() -> Module {
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
gen_valid_oi_local_facts_local_carried_existing_producer_module_from_helpers(
i32_func_type,
i64_func_type,
Expr::new([
Instruction::i32_const(I32(3)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(0x7f)),
]),
Expr::new([
Instruction::i32_const(I32(4)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i64_const(I64(0x7fffffffL)),
]),
Some(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
),
)
}
///|
fn gen_valid_oi_local_facts_local_carried_existing_producer_module_from_helpers(
i32_func_type : RecType,
i64_func_type : RecType,
i32_helper_body : Expr,
i64_helper_body : Expr,
global_sec : GlobalSec?,
) -> Module {
let mut mod = Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_precompute_void_func_type(),
i32_func_type,
i64_func_type,
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(2U)]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_add(),
Instruction::i32_extend8s(),
Instruction::drop(),
Instruction::call(FuncIdx::new(2U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_const(I64(0L)),
Instruction::i64_add(),
Instruction::i64_extend32s(),
Instruction::drop(),
]),
),
Func::new(Locals::empty(), i32_helper_body),
Func::new(Locals::empty(), i64_helper_body),
]),
)
match global_sec {
Some(sec) => mod = mod.with_global_sec(sec)
None => ()
}
mod
}
///|
fn gen_valid_oi_local_facts_existing_producer_module_from_helpers(
i32_func_type : RecType,
i64_func_type : RecType,
i32_helper_body : Expr,
i64_helper_body : Expr,
global_sec : GlobalSec?,
) -> Module {
let mut mod = Module::new()
.with_type_sec(
TypeSec::new([
gen_valid_precompute_void_func_type(),
i32_func_type,
i64_func_type,
]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(2U)]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_extend8s(),
Instruction::drop(),
Instruction::call(FuncIdx::new(2U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_extend32s(),
Instruction::drop(),
]),
),
Func::new(Locals::empty(), i32_helper_body),
Func::new(Locals::empty(), i64_helper_body),
]),
)
match global_sec {
Some(sec) => mod = mod.with_global_sec(sec)
None => ()
}
mod
}
///|
fn gen_valid_oi_memory_bulk_direct_body() -> Array[Instruction] {
let out : Array[Instruction] = []
let mem_idx = MemIdx::new(0U)
let sizes = [0, 1, 2, 3, 4, 5, 8, 16]
for size in sizes {
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(size)))
out.push(Instruction::memory_copy(mem_idx, mem_idx))
out.push(Instruction::i32_const(I32(0)))
out.push(Instruction::i32_const(I32(7)))
out.push(Instruction::i32_const(I32(size)))
out.push(Instruction::memory_fill(mem_idx))
}
out.push(Instruction::i32_const(I32(4)))
out.push(Instruction::i32_load(MemArg::new(2U, None, 12UL)))
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(8)))
out.push(Instruction::i32_const(I32(9)))
out.push(Instruction::i32_store(MemArg::new(2U, None, 16UL)))
out
}
///|
fn gen_valid_oi_memory_bulk_memory64_body() -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
[
Instruction::i64_const(I64(1L)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_const(I64(0L)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::memory_fill(mem_idx),
Instruction::i64_const(I64(8L)),
Instruction::i64_load(MemArg::new(3U, None, 24UL)),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_memory_bulk_live_effect_trap_body() -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
[
Instruction::i32_const(I32(1)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(1)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::i32_const(I32(0)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::i32_div_u(),
Instruction::drop(),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(9)),
Instruction::i32_const(I32(1)),
Instruction::memory_fill(mem_idx),
],
None,
),
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_memory_bulk_call_wrapped_body() -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
[
Instruction::call(FuncIdx::new(1U)),
Instruction::call(FuncIdx::new(2U)),
Instruction::i32_const(I32(1)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(0x7f)),
Instruction::i32_const(I32(1)),
Instruction::memory_fill(mem_idx),
Instruction::call(FuncIdx::new(2U)),
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(8)),
Instruction::memory_copy(mem_idx, mem_idx),
]
}
///|
fn gen_valid_oi_memory_bulk_store_mask_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(0x1234)),
Instruction::i32_const(I32(0xff)),
Instruction::i32_and(),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::i32_const(I32(2)),
Instruction::i32_const(I32(0x12345678)),
Instruction::i32_const(I32(0xffff)),
Instruction::i32_and(),
Instruction::i32_store16(MemArg::new(1U, None, 0UL)),
Instruction::i32_const(I32(4)),
Instruction::i64_const(I64(0x1234L)),
Instruction::i64_const(I64(0xffL)),
Instruction::i64_and(),
Instruction::i64_store8(MemArg::new(0U, None, 0UL)),
]
}
///|
fn gen_valid_oi_memory_bulk_dynamic_i32_body() -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
[
Instruction::i32_const(I32(2)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_const(I32(0xaa)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::memory_fill(mem_idx),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_memory_bulk_multi_memory_body() -> Array[Instruction] {
let mem0 = MemIdx::new(0U)
let mem1 = MemIdx::new(1U)
[
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(1)),
Instruction::memory_copy(mem1, mem0),
Instruction::i32_const(I32(2)),
Instruction::i32_const(I32(0x7f)),
Instruction::i32_const(I32(2)),
Instruction::memory_fill(mem1),
Instruction::i32_const(I32(0)),
Instruction::i32_load8u(MemArg::new(0U, Some(mem1), 0UL)),
Instruction::drop(),
Instruction::i32_const(I32(4)),
Instruction::i32_const(I32(0xaa)),
Instruction::i32_store8(MemArg::new(0U, Some(mem1), 0UL)),
]
}
///|
fn gen_valid_oi_memory_bulk_random_address(seed : UInt64) -> Int32 {
((seed * 1103515245UL + 12345UL) % 65519UL + 17UL).to_int()
}
///|
fn gen_valid_oi_memory_bulk_random_address_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
let addr = gen_valid_oi_memory_bulk_random_address(seed)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(1)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::i32_const(I32(addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_memory_bulk_multi_memory_random_address_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(1U)
let addr = gen_valid_oi_memory_bulk_random_address(seed)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(1)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::i32_const(I32(addr)),
Instruction::i32_load8u(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_memory_bulk_cross_memory_random_address_body(
seed : UInt64,
) -> Array[Instruction] {
let src_mem = MemIdx::new(0U)
let dst_mem = MemIdx::new(1U)
let addr = gen_valid_oi_memory_bulk_random_address(seed)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(1)),
Instruction::memory_copy(dst_mem, src_mem),
Instruction::i32_const(I32(addr)),
Instruction::i32_load8u(MemArg::new(0U, Some(dst_mem), 0UL)),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_memory_bulk_memory64_cross_memory_random_address_body(
seed : UInt64,
) -> Array[Instruction] {
let src_mem = MemIdx::new(0U)
let dst_mem = MemIdx::new(1U)
let addr = gen_valid_oi_memory_bulk_random_address(seed).to_int64()
[
Instruction::i64_const(I64(addr)),
Instruction::i64_const(I64(addr)),
Instruction::i64_const(I64(1L)),
Instruction::memory_copy(dst_mem, src_mem),
Instruction::i64_const(I64(addr)),
Instruction::i64_load8u(MemArg::new(0U, Some(dst_mem), 0UL)),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_memory_bulk_cross_memory_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let src_mem = MemIdx::new(0U)
let dst_mem = MemIdx::new(1U)
let addr = gen_valid_oi_memory_bulk_random_address(seed)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_load8u(MemArg::new(0U, Some(dst_mem), 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(1)),
Instruction::memory_copy(dst_mem, src_mem),
Instruction::i32_const(I32(addr)),
Instruction::i32_load8u(MemArg::new(0U, Some(dst_mem), 0UL)),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, Some(dst_mem), 0UL)),
]
}
///|
fn gen_valid_oi_memory_bulk_memory64_cross_memory_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let src_mem = MemIdx::new(0U)
let dst_mem = MemIdx::new(1U)
let addr = gen_valid_oi_memory_bulk_random_address(seed).to_int64()
[
Instruction::i64_const(I64(addr)),
Instruction::i64_load8u(MemArg::new(0U, Some(dst_mem), 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i64_const(I64(addr)),
Instruction::i64_const(I64(addr)),
Instruction::i64_const(I64(1L)),
Instruction::memory_copy(dst_mem, src_mem),
Instruction::i64_const(I64(addr)),
Instruction::i64_load8u(MemArg::new(0U, Some(dst_mem), 0UL)),
Instruction::drop(),
Instruction::i64_const(I64(addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_store8(MemArg::new(0U, Some(dst_mem), 0UL)),
]
}
///|
fn gen_valid_oi_memory_bulk_runtime_restore_addresses(
seed : UInt64,
) -> (Int32, Int32) {
let src_addr = gen_valid_oi_memory_bulk_random_address(seed)
let dst_addr = if src_addr < 65000 { src_addr + 16 } else { src_addr - 16 }
(src_addr, dst_addr)
}
///|
fn gen_valid_oi_memory_bulk_runtime_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
let (src_addr, dst_addr) = gen_valid_oi_memory_bulk_runtime_restore_addresses(
seed,
)
[
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_const(I32(src_addr)),
Instruction::i32_const(I32(1)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_fill_restore_address(seed : UInt64) -> Int32 {
gen_valid_oi_memory_bulk_random_address(seed ^ 0x51UL)
}
///|
fn gen_valid_oi_memory_bulk_runtime_fill_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(seed)
[
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_const(I32(0x2a)),
Instruction::i32_const(I32(1)),
Instruction::memory_fill(mem_idx),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_runtime_call_fill_restore_body() -> Array[
Instruction,
] {
let mem_idx = MemIdx::new(0U)
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(1U)),
Instruction::call(FuncIdx::new(2U)),
Instruction::call(FuncIdx::new(3U)),
Instruction::memory_fill(mem_idx),
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::call(FuncIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_runtime_call_restore_copy_body() -> Array[
Instruction,
] {
let mem_idx = MemIdx::new(0U)
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(1U)),
Instruction::call(FuncIdx::new(2U)),
Instruction::call(FuncIdx::new(3U)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::call(FuncIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_runtime_localtee_restore_copy_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
let (src_addr, dst_addr) = gen_valid_oi_memory_bulk_runtime_restore_addresses(
seed,
)
[
Instruction::i32_const(I32(dst_addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::i32_const(I32(src_addr)),
Instruction::local_tee(LocalIdx::new(3U)),
Instruction::i32_const(I32(1)),
Instruction::local_tee(LocalIdx::new(4U)),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_runtime_select_restore_copy_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
let (src_addr, dst_addr) = gen_valid_oi_memory_bulk_runtime_restore_addresses(
seed,
)
[
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::i32_const(I32(src_addr)),
Instruction::i32_const(I32(src_addr)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::memory_copy(mem_idx, mem_idx),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
]
}
///|
fn gen_valid_oi_memory_bulk_runtime_select_fill_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(seed)
[
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::i32_const(I32(0x2a)),
Instruction::i32_const(I32(0x2a)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::memory_fill(mem_idx),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
]
}
///|
fn gen_valid_oi_memory_bulk_multi_memory_fill_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(1U)
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(seed)
[
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_const(I32(0x2a)),
Instruction::i32_const(I32(1)),
Instruction::memory_fill(mem_idx),
Instruction::i32_const(I32(dst_addr)),
Instruction::i32_load8u(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(dst_addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_memory64_fill_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(0U)
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(seed).to_int64()
[
Instruction::i64_const(I64(dst_addr)),
Instruction::i64_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i64_const(I64(dst_addr)),
Instruction::i32_const(I32(0x2a)),
Instruction::i64_const(I64(1L)),
Instruction::memory_fill(mem_idx),
Instruction::i64_const(I64(dst_addr)),
Instruction::i64_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i64_const(I64(dst_addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_memory64_multi_memory_fill_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(1U)
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(seed).to_int64()
[
Instruction::i64_const(I64(dst_addr)),
Instruction::i64_load8u(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i64_const(I64(dst_addr)),
Instruction::i32_const(I32(0x2a)),
Instruction::i64_const(I64(1L)),
Instruction::memory_fill(mem_idx),
Instruction::i64_const(I64(dst_addr)),
Instruction::i64_load8u(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i64_const(I64(dst_addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_store8(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_memory64_multi_memory_localtee_fill_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let mem_idx = MemIdx::new(1U)
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(seed).to_int64()
[
Instruction::i64_const(I64(dst_addr)),
Instruction::i64_load8u(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i64_const(I64(dst_addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_const(I32(0x2a)),
Instruction::i64_const(I64(1L)),
Instruction::memory_fill(mem_idx),
Instruction::i64_const(I64(dst_addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_load8u(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i64_const(I64(dst_addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_store8(MemArg::new(0U, Some(mem_idx), 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_wait_notify_body() -> Array[Instruction] {
let memarg32 = MemArg::new(2U, None, 0UL)
let memarg64 = MemArg::new(3U, None, 0UL)
[
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(1)),
Instruction::memory_atomic_notify(memarg32),
Instruction::drop(),
Instruction::i32_const(I32(0)),
Instruction::i32_const(I32(1)),
Instruction::i64_const(I64(0L)),
Instruction::memory_atomic_wait32(memarg32),
Instruction::drop(),
Instruction::i32_const(I32(8)),
Instruction::i64_const(I64(1L)),
Instruction::i64_const(I64(0L)),
Instruction::memory_atomic_wait64(memarg64),
Instruction::drop(),
Instruction::i32_const(I32(0)),
Instruction::i32_load(memarg32),
Instruction::drop(),
Instruction::i32_const(I32(8)),
Instruction::i64_load(memarg64),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_xchg_restore_body() -> Array[
Instruction,
] {
let i32_memarg = MemArg::new(2U, None, 64UL)
let i64_memarg = MemArg::new(3U, None, 72UL)
[
Instruction::i32_const(I32(0)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(0)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::atomic_rmw(AtomicRmwOp::i32_xchg(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(0)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::atomic_rmw(AtomicRmwOp::i64_xchg(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_random_address(
seed : UInt64,
) -> Int32 {
let raw = gen_valid_oi_memory_bulk_random_address(seed ^ 0xa7UL)
raw % 8000 * 8 + 64
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_random_xchg_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::atomic_rmw(AtomicRmwOp::i32_xchg(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::atomic_rmw(AtomicRmwOp::i64_xchg(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_random_add_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_add(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_add(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_localtee_add_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_add(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_add(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_localtee_xchg_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::atomic_rmw(AtomicRmwOp::i32_xchg(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::atomic_rmw(AtomicRmwOp::i64_xchg(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_localtee_cmpxchg_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::atomic_cmpxchg(AtomicCmpxchgOp::i32(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::atomic_cmpxchg(AtomicCmpxchgOp::i64(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_localtee_sub_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_sub(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_sub(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_localtee_xor_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_xor(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_xor(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_localtee_or_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_or(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_or(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_localtee_and_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i32_const(I32(-1)),
Instruction::atomic_rmw(AtomicRmwOp::i32_and(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_tee(LocalIdx::new(2U)),
Instruction::i64_const(I64(-1L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_and(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_call_add_restore_body() -> Array[
Instruction,
] {
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_add(), i32_memarg),
Instruction::drop(),
Instruction::call(FuncIdx::new(1U)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::call(FuncIdx::new(1U)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_add(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_add_address(
addr : Int32,
alt_addr : Int32,
) -> Array[Instruction] {
[
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(alt_addr)),
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::select(types=Some([ValType::i32()])),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_add_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
let body = gen_valid_oi_memory_bulk_shared_atomic_select_add_address(
addr, alt_addr,
)
body.append([
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_add(), i32_memarg),
Instruction::drop(),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_add(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
])
body
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_xchg_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
let body = gen_valid_oi_memory_bulk_shared_atomic_select_add_address(
addr, alt_addr,
)
body.append([
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::atomic_rmw(AtomicRmwOp::i32_xchg(), i32_memarg),
Instruction::drop(),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::atomic_rmw(AtomicRmwOp::i64_xchg(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
])
body
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_cmpxchg_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
let body = gen_valid_oi_memory_bulk_shared_atomic_select_add_address(
addr, alt_addr,
)
body.append([
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::atomic_cmpxchg(AtomicCmpxchgOp::i32(), i32_memarg),
Instruction::drop(),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::atomic_cmpxchg(AtomicCmpxchgOp::i64(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
])
body
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_sub_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
let body = gen_valid_oi_memory_bulk_shared_atomic_select_add_address(
addr, alt_addr,
)
body.append([
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_sub(), i32_memarg),
Instruction::drop(),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_sub(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
])
body
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_xor_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
let body = gen_valid_oi_memory_bulk_shared_atomic_select_add_address(
addr, alt_addr,
)
body.append([
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_xor(), i32_memarg),
Instruction::drop(),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_xor(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
])
body
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_or_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
let body = gen_valid_oi_memory_bulk_shared_atomic_select_add_address(
addr, alt_addr,
)
body.append([
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_or(), i32_memarg),
Instruction::drop(),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_or(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
])
body
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_and_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
let body = gen_valid_oi_memory_bulk_shared_atomic_select_add_address(
addr, alt_addr,
)
body.append([
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i32_const(I32(-1)),
Instruction::atomic_rmw(AtomicRmwOp::i32_and(), i32_memarg),
Instruction::drop(),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
])
body.append(
gen_valid_oi_memory_bulk_shared_atomic_select_add_address(addr, alt_addr),
)
body.append([
Instruction::i64_const(I64(-1L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_and(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
])
body
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_random_sub_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_sub(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_sub(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_random_xor_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_xor(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_xor(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_random_or_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(0)),
Instruction::atomic_rmw(AtomicRmwOp::i32_or(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::i64_const(I64(0L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_or(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_random_and_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::i32_const(I32(-1)),
Instruction::atomic_rmw(AtomicRmwOp::i32_and(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::i64_const(I64(-1L)),
Instruction::atomic_rmw(AtomicRmwOp::i64_and(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_random_cmpxchg_restore_body(
seed : UInt64,
) -> Array[Instruction] {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let i32_memarg = MemArg::new(2U, None, 0UL)
let i64_memarg = MemArg::new(3U, None, 8UL)
[
Instruction::i32_const(I32(addr)),
Instruction::i32_atomic_load(i32_memarg),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(addr)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::atomic_cmpxchg(AtomicCmpxchgOp::i32(), i32_memarg),
Instruction::drop(),
Instruction::i32_const(I32(addr)),
Instruction::i64_atomic_load(i64_memarg),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(addr)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::atomic_cmpxchg(AtomicCmpxchgOp::i64(), i64_memarg),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_runtime_store8_mask_restore_body() -> Array[
Instruction,
] {
[
Instruction::i32_const(I32(64)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(64)),
Instruction::i32_const(I32(0x12342a)),
Instruction::i32_const(I32(0xff)),
Instruction::i32_and(),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::i32_const(I32(64)),
Instruction::i32_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(72)),
Instruction::i64_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::i32_const(I32(72)),
Instruction::i64_const(I64(0x1122334455667788L)),
Instruction::i64_const(I64(0xffL)),
Instruction::i64_and(),
Instruction::i64_store8(MemArg::new(0U, None, 0UL)),
Instruction::i32_const(I32(72)),
Instruction::i64_load8u(MemArg::new(0U, None, 0UL)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::i32_const(I32(64)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i32_store8(MemArg::new(0U, None, 0UL)),
Instruction::i32_const(I32(72)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::i64_store8(MemArg::new(0U, None, 0UL)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::i64_extend_i32u(),
Instruction::local_get(LocalIdx::new(3U)),
Instruction::i64_const(I64(8L)),
Instruction::i64_shl(),
Instruction::i64_xor(),
]
}
///|
fn gen_valid_oi_memory_bulk_call_wrapped_module() -> Module {
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
Module::new()
.with_type_sec(
TypeSec::new([gen_valid_precompute_void_func_type(), i32_func_type]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(1U)]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new(gen_valid_oi_memory_bulk_call_wrapped_body()),
),
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(0))])),
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(8))])),
]),
)
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
}
///|
fn gen_valid_oi_memory_bulk_runtime_call_fill_restore_module(
seed : UInt64,
) -> Module {
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(seed)
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
Module::new()
.with_type_sec(TypeSec::new([i32_func_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i32()]),
Expr::new(gen_valid_oi_memory_bulk_runtime_call_fill_restore_body()),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(dst_addr))]),
),
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(0x2a))])),
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(1))])),
]),
)
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(dst_addr))]),
),
b"\x0d",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_call_add_restore_module(
seed : UInt64,
) -> Module {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let addr_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
Module::new()
.with_type_sec(TypeSec::new([run_type, addr_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new(
gen_valid_oi_memory_bulk_shared_atomic_call_add_restore_body(),
),
),
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(addr))])),
]),
)
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_add_restore_module(
seed : UInt64,
) -> Module {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([run_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(1))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new(
gen_valid_oi_memory_bulk_shared_atomic_select_add_restore_body(seed),
),
),
]),
)
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(alt_addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_xchg_restore_module(
seed : UInt64,
) -> Module {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([run_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(1))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new(
gen_valid_oi_memory_bulk_shared_atomic_select_xchg_restore_body(seed),
),
),
]),
)
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(alt_addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_sub_restore_module(
seed : UInt64,
) -> Module {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([run_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(1))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new(
gen_valid_oi_memory_bulk_shared_atomic_select_sub_restore_body(seed),
),
),
]),
)
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(alt_addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_xor_restore_module(
seed : UInt64,
) -> Module {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([run_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(1))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new(
gen_valid_oi_memory_bulk_shared_atomic_select_xor_restore_body(seed),
),
),
]),
)
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(alt_addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_or_restore_module(
seed : UInt64,
) -> Module {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([run_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(1))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new(
gen_valid_oi_memory_bulk_shared_atomic_select_or_restore_body(seed),
),
),
]),
)
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(alt_addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_and_restore_module(
seed : UInt64,
) -> Module {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([run_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(1))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new(
gen_valid_oi_memory_bulk_shared_atomic_select_and_restore_body(seed),
),
),
]),
)
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(alt_addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_shared_atomic_select_cmpxchg_restore_module(
seed : UInt64,
) -> Module {
let addr = gen_valid_oi_memory_bulk_shared_atomic_random_address(seed)
let alt_addr = addr + 16
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
Module::new()
.with_type_sec(TypeSec::new([run_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(1))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i64()]),
Expr::new(
gen_valid_oi_memory_bulk_shared_atomic_select_cmpxchg_restore_body(
seed,
),
),
),
]),
)
.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(alt_addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
Export::new(Name::from_string("memory"), ExternIdx::mem(MemIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_memory_bulk_runtime_call_restore_copy_module(
seed : UInt64,
) -> Module {
let (src_addr, dst_addr) = gen_valid_oi_memory_bulk_runtime_restore_addresses(
seed,
)
let i32_func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
Module::new()
.with_type_sec(TypeSec::new([i32_func_type]))
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
TypeIdx::new(0U),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i32()]),
Expr::new(gen_valid_oi_memory_bulk_runtime_call_restore_copy_body()),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(dst_addr))]),
),
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(src_addr))]),
),
Func::new(Locals::empty(), Expr::new([Instruction::i32_const(I32(1))])),
]),
)
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(src_addr))]),
),
b"\x07",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(dst_addr))]),
),
b"\x0d",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
}
///|
fn gen_valid_oi_ref_gc_profile_body(case : Int32) -> Array[Instruction] {
let any = HeapType::abs(AbsHeapType::any())
let eq = HeapType::abs(AbsHeapType::eq())
let out : Array[Instruction] = []
match case {
1 => {
out.push(Instruction::ref_null(any))
out.push(Instruction::local_set(LocalIdx::new(0U)))
out.push(Instruction::local_get(LocalIdx::new(0U)))
out.push(Instruction::ref_is_null())
out.push(Instruction::drop())
out.push(Instruction::local_get(LocalIdx::new(0U)))
out.push(Instruction::ref_test(true, any))
out.push(Instruction::drop())
out.push(Instruction::local_get(LocalIdx::new(0U)))
out.push(Instruction::ref_cast(true, any))
out.push(Instruction::drop())
}
2 => {
gen_valid_append_basic_ref_br_on_cast_pair(out, true, true)
gen_valid_append_basic_ref_br_on_cast_pair(out, true, false)
gen_valid_append_basic_ref_br_on_cast_pair(out, false, false)
}
_ => {
gen_valid_append_basic_ref_is_null(out, any)
gen_valid_append_basic_ref_is_null(
out,
HeapType::abs(AbsHeapType::none()),
)
gen_valid_append_basic_ref_test_cast_pair(out, any, any, true)
gen_valid_append_basic_ref_test_cast_pair(out, any, any, false)
out.push(Instruction::ref_null(eq))
out.push(Instruction::ref_null(eq))
out.push(Instruction::ref_eq())
out.push(Instruction::drop())
out.push(Instruction::i32_const(I32(31)))
out.push(Instruction::ref_i31())
out.push(Instruction::drop())
}
}
out
}
///|
fn gen_valid_dead_code_elimination_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config ==
GenValidConfig::for_profile(DeadCodeEliminationBlockSuffixProfile) {
DeadCodeEliminationBlockSuffixProfile
} else if config ==
GenValidConfig::for_profile(DeadCodeEliminationIfBothArmsProfile) {
DeadCodeEliminationIfBothArmsProfile
} else if config ==
GenValidConfig::for_profile(DeadCodeEliminationIfConditionProfile) {
DeadCodeEliminationIfConditionProfile
} else if config ==
GenValidConfig::for_profile(DeadCodeEliminationLoopBodyProfile) {
DeadCodeEliminationLoopBodyProfile
} else if config ==
GenValidConfig::for_profile(DeadCodeEliminationTryTableProfile) {
DeadCodeEliminationTryTableProfile
} else if config ==
GenValidConfig::for_profile(DeadCodeEliminationTryTableCatchRefProfile) {
DeadCodeEliminationTryTableCatchRefProfile
} else if config ==
GenValidConfig::for_profile(
DeadCodeEliminationBranchPayloadForwarderProfile,
) {
DeadCodeEliminationBranchPayloadForwarderProfile
} else if config ==
GenValidConfig::for_profile(DeadCodeEliminationPrefixBranchPayloadProfile) {
DeadCodeEliminationPrefixBranchPayloadProfile
} else if config ==
GenValidConfig::for_profile(DeadCodeEliminationSplitLocalSetWrapperProfile) {
DeadCodeEliminationSplitLocalSetWrapperProfile
} else if config ==
GenValidConfig::for_profile(DeadCodeEliminationStructuredPrefixProfile) {
DeadCodeEliminationStructuredPrefixProfile
} else if config ==
GenValidConfig::for_profile(
DeadCodeEliminationEffectfulStructuredPrefixProfile,
) {
DeadCodeEliminationEffectfulStructuredPrefixProfile
} else {
DeadCodeEliminationNonControlProfile
}
}
///|
fn gen_valid_dead_code_elimination_non_control_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(1)),
Instruction::unreachable_(),
Instruction::i32_const(I32(0)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::drop(),
]
}
///|
fn gen_valid_dead_code_elimination_block_suffix_body() -> Array[Instruction] {
[
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::drop(),
Instruction::unreachable_(),
Instruction::i32_const(I32(2)),
Instruction::drop(),
]),
),
]
}
///|
fn gen_valid_dead_code_elimination_if_both_arms_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::unreachable_()],
Some([Instruction::unreachable_()]),
),
Instruction::drop(),
]
}
///|
fn gen_valid_dead_code_elimination_if_condition_body() -> Array[Instruction] {
[
Instruction::unreachable_(),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(1))],
Some([Instruction::i32_const(I32(2))]),
),
Instruction::drop(),
]
}
///|
fn gen_valid_dead_code_elimination_loop_body_body() -> Array[Instruction] {
[
Instruction::loop_(
BlockType::void_(),
Expr::new([Instruction::unreachable_()]),
),
]
}
///|
fn gen_valid_dead_code_elimination_try_table_body() -> Array[Instruction] {
[
Instruction::try_table(
BlockType::val_type(ValType::i32()),
[],
Expr::new([Instruction::unreachable_()]),
),
]
}
///|
fn gen_valid_dead_code_elimination_try_table_catch_ref_body() -> Array[
Instruction,
] {
[
Instruction::block(
BlockType::val_type(ValType::ref_null_exn()),
Expr::new([
Instruction::try_table(
BlockType::val_type(ValType::ref_null_exn()),
[Catch::ref_(TagIdx::new(0U), LabelIdx::new(0U))],
Expr::new([
Instruction::throw_(TagIdx::new(0U)),
Instruction::ref_null(HeapType::abs(AbsHeapType::exn())),
]),
),
]),
),
Instruction::drop(),
]
}
///|
fn gen_valid_dead_code_elimination_branch_payload_forwarder_body() -> Array[
Instruction,
] {
[
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br(LabelIdx::new(0U)),
Instruction::unreachable_(),
]),
),
Instruction::br(LabelIdx::new(1U)),
Instruction::unreachable_(),
]),
),
Instruction::unreachable_(),
]),
),
]
}
///|
fn gen_valid_dead_code_elimination_prefix_branch_payload_body() -> Array[
Instruction,
] {
[
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::i32_const(I32(7)), Instruction::drop()]),
),
Instruction::i32_const(I32(9)),
Instruction::br(LabelIdx::new(0U)),
Instruction::unreachable_(),
]),
),
]
}
///|
fn gen_valid_dead_code_elimination_split_local_set_wrapper_body() -> Array[
Instruction,
] {
[
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::block(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[
Instruction::i32_const(I32(7)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::br(LabelIdx::new(1U)),
],
Some([
Instruction::i32_const(I32(9)),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::br(LabelIdx::new(3U)),
]),
),
Instruction::br(LabelIdx::new(1U)),
Instruction::unreachable_(),
]),
),
Instruction::local_get(LocalIdx::new(3U)),
]),
),
Instruction::br(LabelIdx::new(1U)),
]),
),
Instruction::i32_const(I32(1)),
]),
),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
]
}
///|
fn gen_valid_dead_code_elimination_structured_prefix_body() -> Array[
Instruction,
] {
[
Instruction::i32_const(I32(1)),
Instruction::drop(),
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::i32_const(I32(2)), Instruction::drop()]),
),
Instruction::i32_const(I32(3)),
Instruction::unreachable_(),
Instruction::i32_const(I32(4)),
Instruction::drop(),
]
}
///|
fn gen_valid_dead_code_elimination_effectful_structured_prefix_body() -> Array[
Instruction,
] {
[
Instruction::i32_const(I32(1)),
Instruction::memory_grow(MemIdx::new(0U)),
Instruction::drop(),
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(0)),
Instruction::i32_load(MemArg::new(0U, None, 0UL)),
Instruction::drop(),
]),
),
Instruction::i32_const(I32(3)),
Instruction::unreachable_(),
Instruction::i32_const(I32(4)),
Instruction::drop(),
]
}
///|
fn gen_valid_dead_code_elimination_profile_module(
config : GenValidConfig,
) -> Module {
let kind = gen_valid_dead_code_elimination_profile_kind(config)
let body = match kind {
DeadCodeEliminationBlockSuffixProfile =>
gen_valid_dead_code_elimination_block_suffix_body()
DeadCodeEliminationIfBothArmsProfile =>
gen_valid_dead_code_elimination_if_both_arms_body()
DeadCodeEliminationIfConditionProfile =>
gen_valid_dead_code_elimination_if_condition_body()
DeadCodeEliminationLoopBodyProfile =>
gen_valid_dead_code_elimination_loop_body_body()
DeadCodeEliminationTryTableProfile =>
gen_valid_dead_code_elimination_try_table_body()
DeadCodeEliminationTryTableCatchRefProfile =>
gen_valid_dead_code_elimination_try_table_catch_ref_body()
DeadCodeEliminationBranchPayloadForwarderProfile =>
gen_valid_dead_code_elimination_branch_payload_forwarder_body()
DeadCodeEliminationPrefixBranchPayloadProfile =>
gen_valid_dead_code_elimination_prefix_branch_payload_body()
DeadCodeEliminationSplitLocalSetWrapperProfile =>
gen_valid_dead_code_elimination_split_local_set_wrapper_body()
DeadCodeEliminationStructuredPrefixProfile =>
gen_valid_dead_code_elimination_structured_prefix_body()
DeadCodeEliminationEffectfulStructuredPrefixProfile =>
gen_valid_dead_code_elimination_effectful_structured_prefix_body()
_ => gen_valid_dead_code_elimination_non_control_body()
}
if kind == DeadCodeEliminationBranchPayloadForwarderProfile {
let func_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [ValType::i32()])),
)
return Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]),
)
}
if kind == DeadCodeEliminationPrefixBranchPayloadProfile {
let func_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
return Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]),
)
}
if kind == DeadCodeEliminationSplitLocalSetWrapperProfile {
let func_type = RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i32()], [ValType::i32()]),
),
)
return Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i32()]),
Expr::new(body),
),
]),
)
}
if kind == DeadCodeEliminationEffectfulStructuredPrefixProfile {
let func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
return Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
.with_code_sec(
CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]),
)
}
if kind == DeadCodeEliminationTryTableCatchRefProfile {
let tag_func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
let func_type = RecType::new(SubType::comp_type(CompType::func([], [])))
return Module::new()
.with_type_sec(TypeSec::new([tag_func_type, func_type]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(0U))]))
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_code_sec(
CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]),
)
}
let func_type = if kind == DeadCodeEliminationTryTableProfile {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()])))
} else {
gen_valid_precompute_void_func_type()
}
Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]))
}
///|
fn gen_valid_oi_tuple_result_types() -> Array[ValType] {
[ValType::i32(), ValType::i64(), ValType::f32(), ValType::f64()]
}
///|
fn gen_valid_oi_tuple_seeded_i32(seed : UInt64) -> Int32 {
((seed * 1664525UL + 1013904223UL) % 4093UL + 3UL).to_int()
}
///|
fn gen_valid_oi_tuple_seeded_f32(seed : UInt64) -> Float {
Float::from_double(((seed ^ 0x35UL) % 97UL).to_int().to_double() + 0.5)
}
///|
fn gen_valid_oi_tuple_seeded_f64(seed : UInt64) -> Double {
((seed ^ 0x51UL) % 193UL).to_int().to_double() + 0.25
}
///|
fn gen_valid_oi_tuple_block_body(case : Int32, seed : UInt64) -> Expr {
let body = if case == 2 {
[
Instruction::local_get(LocalIdx::new(0U)),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(Float::from_double(33.0))),
Instruction::f64_const(F64(44.0)),
]
} else if case == 3 || case == 9 || case == 17 {
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(Float::from_double(33.0))),
Instruction::f64_const(F64(44.0)),
]
} else if case == 6 {
[
Instruction::i32_const(I32(88)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(Float::from_double(33.0))),
Instruction::f64_const(F64(44.0)),
]
} else if case == 7 {
[
Instruction::i32_const(I32(111)),
Instruction::i32_const(I32(222)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(Float::from_double(33.0))),
Instruction::f64_const(F64(44.0)),
]
} else if case == 10 || case == 11 {
[
Instruction::i32_const(I32(111)),
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(Float::from_double(33.0))),
Instruction::f64_const(F64(44.0)),
]
} else if case == 8 {
[
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::i32_div_s(),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(Float::from_double(33.0))),
Instruction::f64_const(F64(44.0)),
]
} else if case == 13 {
[
Instruction::i32_const(I32(gen_valid_oi_tuple_seeded_i32(seed))),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::i32_div_s(),
Instruction::drop(),
Instruction::f32_const(F32(gen_valid_oi_tuple_seeded_f32(seed))),
Instruction::f64_const(F64(gen_valid_oi_tuple_seeded_f64(seed))),
]
} else if case == 4 || case == 5 || case == 12 {
[
Instruction::i32_const(I32(11)),
Instruction::call(FuncIdx::new(1U)),
Instruction::f32_const(F32(Float::from_double(33.0))),
Instruction::f64_const(F64(44.0)),
]
} else {
[
Instruction::i32_const(I32(11)),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(Float::from_double(33.0))),
Instruction::f64_const(F64(44.0)),
]
}
Expr::new(body)
}
///|
fn gen_valid_oi_tuple_selected_lane_prefix(
case : Int32,
seed : UInt64,
block_type_idx : TypeIdx,
) -> Array[Instruction] {
let i32_local_idx = LocalIdx::new(0U)
let i64_local_idx = LocalIdx::new(1U)
let f32_local_idx = LocalIdx::new(2U)
let f64_local_idx = LocalIdx::new(3U)
let scratch_i32_local_idx = i32_local_idx
let instrs : Array[Instruction] = []
if case == 2 {
instrs.push(Instruction::i32_const(I32(99)))
instrs.push(Instruction::local_set(i32_local_idx))
}
let selected_locals = if case == 1 {
[i32_local_idx, i64_local_idx, f32_local_idx, f64_local_idx]
} else if case == 12 {
[i32_local_idx, i64_local_idx]
} else {
[i32_local_idx]
}
for selected_local in selected_locals {
instrs.push(
Instruction::block(
BlockType::type_idx(block_type_idx),
gen_valid_oi_tuple_block_body(case, seed),
),
)
instrs.push(Instruction::local_set(f64_local_idx))
instrs.push(Instruction::local_set(f32_local_idx))
instrs.push(Instruction::local_set(i64_local_idx))
instrs.push(Instruction::local_set(i32_local_idx))
instrs.push(Instruction::local_get(selected_local))
if case == 16 || case == 17 {
instrs.push(Instruction::local_set(scratch_i32_local_idx))
instrs.push(Instruction::local_get(scratch_i32_local_idx))
}
instrs.push(Instruction::drop())
}
instrs
}
///|
fn gen_valid_oi_tuple_runtime_selected_module(seed : UInt64) -> Module {
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let block_type = RecType::new(
SubType::comp_type(CompType::func([], gen_valid_oi_tuple_result_types())),
)
let block_type_idx = TypeIdx::new(1U)
Module::new()
.with_type_sec(TypeSec::new([run_type, block_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
Expr::new([
Instruction::block(
BlockType::type_idx(block_type_idx),
Expr::new([
Instruction::i32_const(I32(gen_valid_oi_tuple_seeded_i32(seed))),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(gen_valid_oi_tuple_seeded_f32(seed))),
Instruction::f64_const(F64(gen_valid_oi_tuple_seeded_f64(seed))),
]),
),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
]),
),
]),
)
}
///|
fn gen_valid_oi_tuple_runtime_effectful_selected_module(
seed : UInt64,
) -> Module {
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let helper_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let block_type = RecType::new(
SubType::comp_type(CompType::func([], gen_valid_oi_tuple_result_types())),
)
Module::new()
.with_type_sec(TypeSec::new([run_type, helper_type, block_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(2U)),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(gen_valid_oi_tuple_seeded_f32(seed))),
Instruction::f64_const(F64(gen_valid_oi_tuple_seeded_f64(seed))),
]),
),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(123)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(gen_valid_oi_tuple_seeded_i32(seed))),
]),
),
]),
)
}
///|
fn gen_valid_oi_tuple_runtime_multi_selected_effectful_module(
seed : UInt64,
) -> Module {
let i32_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let helper_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let block_type = RecType::new(
SubType::comp_type(CompType::func([], gen_valid_oi_tuple_result_types())),
)
fn body_for(selected_local : LocalIdx, seed : UInt64) -> Expr {
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(3U)),
Expr::new([
Instruction::i32_const(I32(gen_valid_oi_tuple_seeded_i32(seed))),
Instruction::call(FuncIdx::new(2U)),
Instruction::f32_const(F32(gen_valid_oi_tuple_seeded_f32(seed))),
Instruction::f64_const(F64(gen_valid_oi_tuple_seeded_f64(seed))),
]),
),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(selected_local),
])
}
Module::new()
.with_type_sec(TypeSec::new([i32_type, i64_type, helper_type, block_type]))
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(2U)]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("run_i32"),
ExternIdx::func(FuncIdx::new(0U)),
),
Export::new(
Name::from_string("run_i64"),
ExternIdx::func(FuncIdx::new(1U)),
),
]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i64(), true),
Expr::new([Instruction::i64_const(I64(0L))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
body_for(LocalIdx::new(0U), seed),
),
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
body_for(LocalIdx::new(1U), seed),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i64_const(I64(123L)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i64_const(I64(22L)),
]),
),
]),
)
}
///|
fn gen_valid_oi_tuple_runtime_effectful_scratch_module(seed : UInt64) -> Module {
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let helper_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let block_type = RecType::new(
SubType::comp_type(CompType::func([], gen_valid_oi_tuple_result_types())),
)
Module::new()
.with_type_sec(TypeSec::new([run_type, helper_type, block_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(2U)),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(gen_valid_oi_tuple_seeded_f32(seed))),
Instruction::f64_const(F64(gen_valid_oi_tuple_seeded_f64(seed))),
]),
),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(123)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(gen_valid_oi_tuple_seeded_i32(seed))),
]),
),
]),
)
}
///|
fn gen_valid_oi_tuple_runtime_mixed_effect_trap_scratch_module(
seed : UInt64,
) -> Module {
let run_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let effect_helper_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let trap_helper_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let block_type = RecType::new(
SubType::comp_type(CompType::func([], gen_valid_oi_tuple_result_types())),
)
Module::new()
.with_type_sec(
TypeSec::new([run_type, effect_helper_type, trap_helper_type, block_type]),
)
.with_func_sec(
FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U), TypeIdx::new(2U)]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(3U)),
Expr::new([
Instruction::call(FuncIdx::new(1U)),
Instruction::call(FuncIdx::new(2U)),
Instruction::f32_const(F32(gen_valid_oi_tuple_seeded_f32(seed))),
Instruction::f64_const(F64(gen_valid_oi_tuple_seeded_f64(seed))),
]),
),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(123)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(gen_valid_oi_tuple_seeded_i32(seed))),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::i64_const(I64(1L)),
Instruction::i64_const(I64(0L)),
Instruction::i64_div_s(),
]),
),
]),
)
}
///|
fn gen_valid_oi_tuple_runtime_all_results_module(seed : UInt64) -> Module {
let i32_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let i64_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i64()])),
)
let f32_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::f32()])),
)
let f64_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::f64()])),
)
let block_type = RecType::new(
SubType::comp_type(CompType::func([], gen_valid_oi_tuple_result_types())),
)
fn body_for(selected_local : LocalIdx, seed : UInt64) -> Expr {
Expr::new([
Instruction::block(
BlockType::type_idx(TypeIdx::new(4U)),
Expr::new([
Instruction::i32_const(I32(gen_valid_oi_tuple_seeded_i32(seed))),
Instruction::i64_const(I64(22L)),
Instruction::f32_const(F32(gen_valid_oi_tuple_seeded_f32(seed))),
Instruction::f64_const(F64(gen_valid_oi_tuple_seeded_f64(seed))),
]),
),
Instruction::local_set(LocalIdx::new(3U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(selected_local),
])
}
Module::new()
.with_type_sec(
TypeSec::new([i32_type, i64_type, f32_type, f64_type, block_type]),
)
.with_func_sec(
FuncSec::new([
TypeIdx::new(0U),
TypeIdx::new(1U),
TypeIdx::new(2U),
TypeIdx::new(3U),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("run_i32"),
ExternIdx::func(FuncIdx::new(0U)),
),
Export::new(
Name::from_string("run_i64"),
ExternIdx::func(FuncIdx::new(1U)),
),
Export::new(
Name::from_string("run_f32"),
ExternIdx::func(FuncIdx::new(2U)),
),
Export::new(
Name::from_string("run_f64"),
ExternIdx::func(FuncIdx::new(3U)),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
body_for(LocalIdx::new(0U), seed),
),
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
body_for(LocalIdx::new(1U), seed),
),
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
body_for(LocalIdx::new(2U), seed),
),
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
body_for(LocalIdx::new(3U), seed),
),
]),
)
}
///|
fn gen_valid_oi_tuple_profile_module(case : Int32, seed : UInt64) -> Module {
if case == 14 {
return gen_valid_oi_tuple_runtime_selected_module(seed)
}
if case == 15 {
return gen_valid_oi_tuple_runtime_effectful_selected_module(seed)
}
if case == 18 {
return gen_valid_oi_tuple_runtime_all_results_module(seed)
}
if case == 19 {
return gen_valid_oi_tuple_runtime_effectful_scratch_module(seed)
}
if case == 20 {
return gen_valid_oi_tuple_runtime_multi_selected_effectful_module(seed)
}
if case == 21 {
return gen_valid_oi_tuple_runtime_mixed_effect_trap_scratch_module(seed)
}
let func_type = gen_valid_precompute_void_func_type()
let helper_result_type = if case == 4 || case == 5 || case == 12 || case == 13 {
ValType::i64()
} else {
ValType::i32()
}
let helper_func_type = RecType::new(
SubType::comp_type(CompType::func([], [helper_result_type])),
)
let block_type = RecType::new(
SubType::comp_type(CompType::func([], gen_valid_oi_tuple_result_types())),
)
let has_helper = case == 3 ||
case == 4 ||
case == 5 ||
case == 9 ||
case == 10 ||
case == 11 ||
case == 17 ||
case == 12 ||
case == 13
let type_defs = if has_helper {
[func_type, helper_func_type, block_type]
} else {
[func_type, block_type]
}
let block_type_idx = if has_helper {
TypeIdx::new(2U)
} else {
TypeIdx::new(1U)
}
let func_types = if has_helper {
[TypeIdx::new(0U), TypeIdx::new(1U)]
} else {
[TypeIdx::new(0U)]
}
let funcs = if has_helper {
let helper_body = if case == 4 || case == 12 || case == 13 {
[
Instruction::i64_const(I64(123L)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i64_const(I64(22L)),
]
} else if case == 5 {
[
Instruction::i64_const(I64(1L)),
Instruction::i64_const(I64(0L)),
Instruction::i64_div_s(),
]
} else if case == 9 || case == 10 || case == 17 {
[
Instruction::i32_const(I32(123)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(77)),
]
} else if case == 11 {
[
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::i32_div_s(),
]
} else {
[Instruction::i32_const(I32(77))]
}
[
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
Expr::new(
gen_valid_oi_tuple_selected_lane_prefix(case, seed, block_type_idx),
),
),
Func::new(Locals::empty(), Expr::new(helper_body)),
]
} else {
[
Func::new(
Locals::from_types([
ValType::i32(),
ValType::i64(),
ValType::f32(),
ValType::f64(),
]),
Expr::new(
gen_valid_oi_tuple_selected_lane_prefix(case, seed, block_type_idx),
),
),
]
}
let mut mod = Module::new()
.with_type_sec(TypeSec::new(type_defs))
.with_func_sec(FuncSec::new(func_types))
.with_code_sec(CodeSec::new(funcs))
if case == 4 ||
case == 9 ||
case == 10 ||
case == 12 ||
case == 13 ||
case == 17 {
let global_type = if case == 4 || case == 12 || case == 13 {
ValType::i64()
} else {
ValType::i32()
}
let init = if case == 4 || case == 12 || case == 13 {
Expr::new([Instruction::i64_const(I64(0L))])
} else {
Expr::new([Instruction::i32_const(I32(0))])
}
mod = mod.with_global_sec(
GlobalSec::new([Global::new(GlobalType::new(global_type, true), init)]),
)
}
mod
}
///|
fn gen_valid_oi_boolean_select_direct_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(11))],
Some([Instruction::i32_const(I32(22))]),
),
Instruction::drop(),
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(1)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::drop(),
Instruction::i32_const(I32(42)),
Instruction::i32_const(I32(13)),
Instruction::i32_const(I32(0)),
Instruction::i32_eqz(),
Instruction::select(types=Some([ValType::i32()])),
Instruction::drop(),
]
}
///|
fn gen_valid_oi_boolean_select_effectful_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(9)),
Instruction::i32_const(I32(9)),
Instruction::call(FuncIdx::new(1U)),
Instruction::select(types=Some([ValType::i32()])),
Instruction::drop(),
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(4)),
Instruction::global_set(GlobalIdx::new(0U)),
],
Some([
Instruction::i32_const(I32(5)),
Instruction::global_set(GlobalIdx::new(0U)),
]),
),
]
}
///|
fn gen_valid_oi_boolean_select_trapping_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::i32_const(I32(9)), Instruction::drop()],
Some([
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(0)),
Instruction::i32_div_u(),
Instruction::drop(),
]),
),
]
}
///|
fn gen_valid_oi_boolean_select_value_if_body() -> Array[Instruction] {
[
Instruction::i32_const(I32(0)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(44))],
Some([Instruction::i32_const(I32(55))]),
),
Instruction::drop(),
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::i32_const(I32(5)), Instruction::drop()],
Some([Instruction::i32_const(I32(6)), Instruction::drop()]),
),
]
}
///|
fn gen_valid_oi_boolean_select_profile_module(case : Int32) -> Module {
let void_type = RecType::new(SubType::comp_type(CompType::func([], [])))
let main_body = match case {
1 => gen_valid_oi_boolean_select_effectful_body()
2 => gen_valid_oi_boolean_select_trapping_body()
3 => gen_valid_oi_boolean_select_value_if_body()
_ => gen_valid_oi_boolean_select_direct_body()
}
if case == 1 {
let helper_type = RecType::new(
SubType::comp_type(CompType::func([], [ValType::i32()])),
)
let helper_body = [
Instruction::i32_const(I32(1)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(1)),
]
Module::new()
.with_type_sec(TypeSec::new([void_type, helper_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(1U)]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(Locals::empty(), Expr::new(main_body)),
Func::new(Locals::empty(), Expr::new(helper_body)),
]),
)
} else {
Module::new()
.with_type_sec(TypeSec::new([void_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([Func::new(Locals::empty(), Expr::new(main_body))]),
)
}
}
///|
fn gen_valid_oi_call_ref_profile_module(case : Int32) -> Module {
let run_type = if case == 5 {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()])))
} else {
gen_valid_precompute_void_func_type()
}
let target_type = if case == 3 {
gen_valid_precompute_void_func_type()
} else if case == 6 || case == 7 || case == 9 {
RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [ValType::i32()])),
)
} else if case == 8 {
RecType::new(
SubType::comp_type(
CompType::func([ValType::i32(), ValType::i64()], [ValType::i64()]),
),
)
} else {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()])))
}
let target_type_idx = TypeIdx::new(1U)
let target_func_idx = FuncIdx::new(1U)
let target_ref = ValType::ref_type(
RefType::new(true, HeapType::new(target_type_idx)),
)
let body = match case {
1 =>
[
Instruction::ref_func(target_func_idx),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::call_ref(target_type_idx),
Instruction::drop(),
]
2 =>
[
Instruction::block(
BlockType::val_type(target_ref),
Expr::new([Instruction::ref_func(target_func_idx)]),
),
Instruction::call_ref(target_type_idx),
Instruction::drop(),
]
3 =>
[
Instruction::block(
BlockType::val_type(target_ref),
Expr::new([Instruction::ref_func(target_func_idx)]),
),
Instruction::return_call_ref(target_type_idx),
]
4 =>
[
Instruction::i32_const(I32(0)),
Instruction::table_get(TableIdx::new(0U)),
Instruction::call_ref(target_type_idx),
Instruction::drop(),
]
5 =>
[
Instruction::i32_const(I32(0)),
Instruction::table_get(TableIdx::new(0U)),
Instruction::return_call_ref(target_type_idx),
]
6 =>
[
Instruction::i32_const(I32(41)),
Instruction::ref_func(target_func_idx),
Instruction::call_ref(target_type_idx),
Instruction::drop(),
]
7 =>
[
Instruction::i32_const(I32(41)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_func(target_func_idx),
Instruction::call_ref(target_type_idx),
Instruction::drop(),
]
8 =>
[
Instruction::i32_const(I32(41)),
Instruction::i64_const(I64(77L)),
Instruction::ref_func(target_func_idx),
Instruction::call_ref(target_type_idx),
Instruction::drop(),
]
9 =>
[
Instruction::i32_const(I32(41)),
Instruction::i32_const(I32(99)),
Instruction::i32_const(I32(1)),
Instruction::select(),
Instruction::ref_func(target_func_idx),
Instruction::call_ref(target_type_idx),
Instruction::drop(),
]
_ =>
[
Instruction::ref_func(target_func_idx),
Instruction::call_ref(target_type_idx),
Instruction::drop(),
]
}
let locals = if case == 1 {
Locals::from_types([target_ref])
} else if case == 7 {
Locals::from_types([ValType::i32()])
} else {
Locals::empty()
}
let mut mod = Module::new()
.with_type_sec(TypeSec::new([run_type, target_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), target_type_idx]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_elem_sec(
ElemSec::new([
Elem::new(ElemMode::declarative(), ElemKind::funcs([target_func_idx])),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(locals, Expr::new(body)),
Func::new(
Locals::empty(),
Expr::new(
if case == 3 {
[]
} else if case == 6 || case == 7 || case == 9 {
[Instruction::local_get(LocalIdx::new(0U))]
} else if case == 8 {
[Instruction::local_get(LocalIdx::new(1U))]
} else {
[Instruction::i32_const(I32(42))]
},
),
),
]),
)
if case == 4 || case == 5 {
mod = mod.with_table_sec(
TableSec::new([
Table::new(
TableType::new(
RefType::new(true, HeapType::new(target_type_idx)),
Limits::i32(1U, Some(1U)),
),
None,
),
]),
)
mod = mod.with_elem_sec(
ElemSec::new([
Elem::new(
ElemMode::active(
TableIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
ElemKind::typed_exprs(
RefType::new(true, HeapType::new(target_type_idx)),
[Expr::new([Instruction::ref_func(target_func_idx)])],
),
),
Elem::new(ElemMode::declarative(), ElemKind::funcs([target_func_idx])),
]),
)
}
mod
}
///|
fn gen_valid_oi_descriptor_gc_profile_module(case : Int32) -> Module {
let described_idx = TypeIdx::new(0U)
let descriptor_idx = TypeIdx::new(1U)
let primary_func_type_idx = TypeIdx::new(2U)
let nullable_null_func_type_idx = TypeIdx::new(3U)
let nonnull_null_func_type_idx = TypeIdx::new(4U)
let described_heap = HeapType::new(described_idx)
let descriptor_heap = HeapType::new(descriptor_idx)
let nullable_described_ref = RefType::new(true, described_heap, exact=true)
let nonnull_described_ref = RefType::new(false, described_heap, exact=true)
let descriptor_ref_type = RefType::new(false, descriptor_heap, exact=true)
let descriptor_ref = ValType::ref_type(descriptor_ref_type)
let type_sec = TypeSec::new([
RecType::group([
SubType::comp_type(
CompType::struct_([]),
metadata=TypeMetadata::new(descriptor=Some(descriptor_idx)),
),
SubType::comp_type(
CompType::struct_([]),
metadata=TypeMetadata::new(describes=Some(described_idx)),
),
]),
RecType::new(SubType::comp_type(CompType::func([], []))),
RecType::new(
SubType::comp_type(
CompType::func([descriptor_ref], [
ValType::ref_type(nullable_described_ref),
]),
),
),
RecType::new(
SubType::comp_type(
CompType::func([descriptor_ref], [
ValType::ref_type(nonnull_described_ref),
]),
),
),
])
if case == 2 {
return Module::new()
.with_type_sec(type_sec)
.with_func_sec(
FuncSec::new([nullable_null_func_type_idx, nonnull_null_func_type_idx]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_null_type(nullable_described_ref),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_cast_desc_eq_type(nullable_described_ref),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_null_type(nullable_described_ref),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::ref_cast_desc_eq_type(nonnull_described_ref),
]),
),
]),
)
}
if case == 3 {
return Module::new()
.with_type_sec(type_sec)
.with_func_sec(
FuncSec::new([nullable_null_func_type_idx, nonnull_null_func_type_idx]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(descriptor_ref, true),
Expr::new([Instruction::struct_new_default(descriptor_idx)]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_null_type(nullable_described_ref),
Instruction::block(
BlockType::val_type(descriptor_ref),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::global_get(GlobalIdx::new(0U)),
]),
),
Instruction::ref_cast_desc_eq_type(nullable_described_ref),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_null_type(nullable_described_ref),
Instruction::block(
BlockType::val_type(descriptor_ref),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::global_get(GlobalIdx::new(0U)),
]),
),
Instruction::ref_cast_desc_eq_type(nonnull_described_ref),
]),
),
]),
)
}
if case == 0 {
return Module::new()
.with_type_sec(type_sec)
.with_func_sec(
FuncSec::new([nullable_null_func_type_idx, nonnull_null_func_type_idx]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_null_type(nullable_described_ref),
Instruction::struct_new_default(descriptor_idx),
Instruction::ref_cast_desc_eq_type(nullable_described_ref),
]),
),
Func::new(
Locals::empty(),
Expr::new([
Instruction::ref_null_type(nullable_described_ref),
Instruction::struct_new_default(descriptor_idx),
Instruction::ref_cast_desc_eq_type(nonnull_described_ref),
]),
),
]),
)
}
Module::new()
.with_type_sec(type_sec)
.with_func_sec(FuncSec::new([primary_func_type_idx]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::struct_new_default(descriptor_idx),
Instruction::struct_new_default_desc(described_idx),
Instruction::ref_get_desc(described_idx),
Instruction::drop(),
Instruction::struct_new_default(descriptor_idx),
Instruction::struct_new_default_desc(described_idx),
Instruction::struct_new_default(descriptor_idx),
Instruction::ref_cast_desc_eq_type(RefType::new(true, described_heap)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_oi_gc_aggregate_effect_body(value : Int32) -> Array[Instruction] {
[
Instruction::global_get(GlobalIdx::new(0U)),
Instruction::i32_const(I32(1)),
Instruction::i32_add(),
Instruction::global_set(GlobalIdx::new(0U)),
Instruction::i32_const(I32(value)),
]
}
///|
fn gen_valid_oi_gc_aggregate_profile_body(
case : Int32,
struct_idx : TypeIdx,
array_idx : TypeIdx,
) -> Array[Instruction] {
match case {
0 =>
[
Instruction::i32_const(I32(10)),
Instruction::i32_const(I32(20)),
Instruction::struct_new(struct_idx),
Instruction::struct_get(struct_idx, U32::new(0U)),
Instruction::drop(),
]
1 =>
[
Instruction::i32_const(I32(10)),
Instruction::call(FuncIdx::new(1U)),
Instruction::struct_new(struct_idx),
Instruction::struct_get(struct_idx, U32::new(0U)),
Instruction::drop(),
]
2 =>
[
Instruction::i32_const(I32(5)),
Instruction::i32_const(I32(6)),
Instruction::array_new_fixed(array_idx, U32::new(2U)),
Instruction::i32_const(I32(1)),
Instruction::array_get(array_idx),
Instruction::drop(),
]
3 =>
[
Instruction::i32_const(I32(5)),
Instruction::call(FuncIdx::new(1U)),
Instruction::array_new_fixed(array_idx, U32::new(2U)),
Instruction::i32_const(I32(0)),
Instruction::array_get(array_idx),
Instruction::drop(),
]
4 =>
[
Instruction::i32_const(I32(5)),
Instruction::i32_const(I32(6)),
Instruction::array_new_fixed(array_idx, U32::new(2U)),
Instruction::i32_const(I32(1)),
Instruction::call(FuncIdx::new(2U)),
Instruction::array_set(array_idx),
]
5 =>
[
Instruction::i32_const(I32(5)),
Instruction::i32_const(I32(6)),
Instruction::array_new_fixed(array_idx, U32::new(2U)),
Instruction::i32_const(I32(2)),
Instruction::call(FuncIdx::new(2U)),
Instruction::array_set(array_idx),
]
6 =>
[
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(3)),
Instruction::array_new(array_idx),
Instruction::array_len(),
Instruction::drop(),
]
7 =>
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(3)),
Instruction::array_new(array_idx),
Instruction::array_len(),
Instruction::drop(),
]
8 =>
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(3)),
Instruction::array_new(array_idx),
Instruction::i32_const(I32(1)),
Instruction::array_get(array_idx),
Instruction::drop(),
]
9 =>
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(3)),
Instruction::array_new(array_idx),
Instruction::i32_const(I32(3)),
Instruction::array_get(array_idx),
Instruction::drop(),
]
10 =>
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(2)),
Instruction::array_new(array_idx),
Instruction::i32_const(I32(1)),
Instruction::i32_const(I32(9)),
Instruction::array_set(array_idx),
]
11 =>
[
Instruction::call(FuncIdx::new(1U)),
Instruction::i32_const(I32(2)),
Instruction::array_new(array_idx),
Instruction::i32_const(I32(1)),
Instruction::call(FuncIdx::new(2U)),
Instruction::array_set(array_idx),
]
12 =>
[
Instruction::i32_const(I32(1)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(5)),
Instruction::i32_const(I32(6)),
Instruction::array_new_fixed(array_idx, U32::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::array_get(array_idx),
Instruction::drop(),
]
13 =>
[
Instruction::i32_const(I32(2)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::i32_const(I32(7)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::array_new(array_idx),
Instruction::array_len(),
Instruction::drop(),
]
_ =>
[
Instruction::i32_const(I32(7)),
Instruction::i32_const(I32(-1)),
Instruction::array_new(array_idx),
Instruction::array_len(),
Instruction::drop(),
]
}
}
///|
fn gen_valid_oi_gc_aggregate_profile_module(case : Int32) -> Module {
let run_type = TypeIdx::new(0U)
let effect_type = TypeIdx::new(1U)
let struct_idx = TypeIdx::new(2U)
let array_idx = TypeIdx::new(3U)
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([], []))),
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()]))),
RecType::new(
SubType::comp_type(
CompType::struct_([
FieldType::new(StorageType::val_type(ValType::i32()), Var),
FieldType::new(StorageType::val_type(ValType::i32()), Var),
]),
),
),
RecType::new(
SubType::comp_type(
CompType::array(
FieldType::new(StorageType::val_type(ValType::i32()), Var),
),
),
),
]),
)
.with_func_sec(FuncSec::new([run_type, effect_type, effect_type]))
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32()]),
Expr::new(
gen_valid_oi_gc_aggregate_profile_body(case, struct_idx, array_idx),
),
),
Func::new(
Locals::empty(),
Expr::new(gen_valid_oi_gc_aggregate_effect_body(11)),
),
Func::new(
Locals::empty(),
Expr::new(gen_valid_oi_gc_aggregate_effect_body(29)),
),
]),
)
}
///|
fn gen_valid_oi_trigger_profile_module(ctx : GenValidContext) -> Module {
let config = ctx.config
let local_facts = config ==
GenValidConfig::for_profile(PassOiLocalFactsProfile)
let boolean_select = config ==
GenValidConfig::for_profile(PassOiBooleanSelectProfile)
let call_ref = config == GenValidConfig::for_profile(PassOiCallRefProfile)
let ref_gc = config == GenValidConfig::for_profile(PassOiRefGcProfile)
let gc_aggregate = config ==
GenValidConfig::for_profile(PassOiGcAggregateProfile)
let descriptor_gc = config ==
GenValidConfig::for_profile(PassOiDescriptorGcProfile)
let memory_bulk = config ==
GenValidConfig::for_profile(PassOiMemoryBulkProfile)
let tuple = config == GenValidConfig::for_profile(PassOiTupleProfile)
let case = gen_valid_oi_trigger_profile_case(ctx)
if tuple {
return gen_valid_oi_tuple_profile_module(case, ctx.root_seed)
}
if boolean_select {
return gen_valid_oi_boolean_select_profile_module(case)
}
if call_ref {
return gen_valid_oi_call_ref_profile_module(case)
}
if descriptor_gc {
return gen_valid_oi_descriptor_gc_profile_module(case)
}
if gc_aggregate {
return gen_valid_oi_gc_aggregate_profile_module(case)
}
if local_facts && case == 3 {
return gen_valid_oi_local_facts_existing_producer_module()
}
if local_facts && case == 4 {
return gen_valid_oi_local_facts_effectful_existing_producer_module()
}
if local_facts && case == 5 {
return gen_valid_oi_local_facts_trapping_existing_producer_module()
}
if local_facts && case == 6 {
return gen_valid_oi_local_facts_localtee_existing_producer_module()
}
if local_facts && case == 8 {
return gen_valid_oi_local_facts_local_carried_existing_producer_module()
}
if local_facts && case == 9 {
return gen_valid_oi_local_facts_effectful_local_carried_existing_producer_module()
}
if memory_bulk && case == 3 {
return gen_valid_oi_memory_bulk_call_wrapped_module()
}
if memory_bulk && case == 19 {
return gen_valid_oi_memory_bulk_runtime_call_fill_restore_module(
ctx.root_seed,
)
}
if memory_bulk && case == 20 {
return gen_valid_oi_memory_bulk_runtime_call_restore_copy_module(
ctx.root_seed,
)
}
if memory_bulk && case == 34 {
return gen_valid_oi_memory_bulk_shared_atomic_call_add_restore_module(
ctx.root_seed,
)
}
if memory_bulk && case == 35 {
return gen_valid_oi_memory_bulk_shared_atomic_select_add_restore_module(
ctx.root_seed,
)
}
if memory_bulk && case == 36 {
return gen_valid_oi_memory_bulk_shared_atomic_select_xchg_restore_module(
ctx.root_seed,
)
}
if memory_bulk && case == 37 {
return gen_valid_oi_memory_bulk_shared_atomic_select_cmpxchg_restore_module(
ctx.root_seed,
)
}
if memory_bulk && case == 38 {
return gen_valid_oi_memory_bulk_shared_atomic_select_sub_restore_module(
ctx.root_seed,
)
}
if memory_bulk && case == 39 {
return gen_valid_oi_memory_bulk_shared_atomic_select_xor_restore_module(
ctx.root_seed,
)
}
if memory_bulk && case == 40 {
return gen_valid_oi_memory_bulk_shared_atomic_select_or_restore_module(
ctx.root_seed,
)
}
if memory_bulk && case == 41 {
return gen_valid_oi_memory_bulk_shared_atomic_select_and_restore_module(
ctx.root_seed,
)
}
let locals = if local_facts {
Locals::from_types([ValType::i32(), ValType::i64()])
} else if ref_gc && case == 1 {
Locals::from_types([
ValType::ref_type(RefType::new(true, HeapType::abs(AbsHeapType::any()))),
])
} else if memory_bulk && case == 1 {
Locals::from_types([ValType::i64()])
} else if memory_bulk && case == 12 {
Locals::from_types([ValType::i64()])
} else if memory_bulk && case == 48 {
Locals::from_types([ValType::i64(), ValType::i64(), ValType::i64()])
} else if memory_bulk && (case == 16 || case == 18) {
Locals::from_types([ValType::i64(), ValType::i64()])
} else if memory_bulk && case == 21 {
Locals::from_types([
ValType::i32(),
ValType::i32(),
ValType::i32(),
ValType::i32(),
ValType::i32(),
])
} else if memory_bulk && (case == 22 || case == 23) {
Locals::from_types([ValType::i32(), ValType::i32()])
} else if memory_bulk &&
(
case == 33 ||
case == 42 ||
case == 43 ||
case == 44 ||
case == 45 ||
case == 46 ||
case == 47
) {
Locals::from_types([ValType::i32(), ValType::i64(), ValType::i32()])
} else if memory_bulk &&
(
case == 24 ||
case == 26 ||
case == 27 ||
case == 28 ||
case == 29 ||
case == 30 ||
case == 31 ||
case == 32
) {
Locals::from_types([ValType::i32(), ValType::i64()])
} else if memory_bulk && case == 25 {
Locals::from_types([
ValType::i32(),
ValType::i32(),
ValType::i64(),
ValType::i64(),
])
} else if memory_bulk && (case == 13 || case == 15 || case == 17) {
Locals::from_types([ValType::i32(), ValType::i32()])
} else if memory_bulk && (case == 5 || case == 11) {
Locals::from_types([ValType::i32()])
} else if config == GenValidConfig::for_profile(PassOiDefaultScalarProfile) {
Locals::from_types([ValType::i32()])
} else if !ref_gc && !memory_bulk && (case == 1 || case == 2) {
Locals::from_types([ValType::i32()])
} else {
Locals::empty()
}
let body = if local_facts {
gen_valid_oi_local_facts_profile_body(case)
} else if ref_gc {
gen_valid_oi_ref_gc_profile_body(case)
} else if memory_bulk {
match case {
1 => gen_valid_oi_memory_bulk_memory64_body()
2 => gen_valid_oi_memory_bulk_live_effect_trap_body()
4 => gen_valid_oi_memory_bulk_store_mask_body()
5 => gen_valid_oi_memory_bulk_dynamic_i32_body()
6 => gen_valid_oi_memory_bulk_multi_memory_body()
7 => gen_valid_oi_memory_bulk_random_address_body(ctx.root_seed)
8 =>
gen_valid_oi_memory_bulk_multi_memory_random_address_body(ctx.root_seed)
9 =>
gen_valid_oi_memory_bulk_cross_memory_random_address_body(ctx.root_seed)
10 =>
gen_valid_oi_memory_bulk_memory64_cross_memory_random_address_body(
ctx.root_seed,
)
11 => gen_valid_oi_memory_bulk_cross_memory_restore_body(ctx.root_seed)
12 =>
gen_valid_oi_memory_bulk_memory64_cross_memory_restore_body(
ctx.root_seed,
)
13 => gen_valid_oi_memory_bulk_runtime_restore_body(ctx.root_seed)
14 => gen_valid_oi_memory_bulk_shared_wait_notify_body()
15 => gen_valid_oi_memory_bulk_runtime_fill_restore_body(ctx.root_seed)
16 => gen_valid_oi_memory_bulk_memory64_fill_restore_body(ctx.root_seed)
17 =>
gen_valid_oi_memory_bulk_multi_memory_fill_restore_body(ctx.root_seed)
18 =>
gen_valid_oi_memory_bulk_memory64_multi_memory_fill_restore_body(
ctx.root_seed,
)
48 =>
gen_valid_oi_memory_bulk_memory64_multi_memory_localtee_fill_restore_body(
ctx.root_seed,
)
21 =>
gen_valid_oi_memory_bulk_runtime_localtee_restore_copy_body(
ctx.root_seed,
)
22 =>
gen_valid_oi_memory_bulk_runtime_select_restore_copy_body(ctx.root_seed)
23 =>
gen_valid_oi_memory_bulk_runtime_select_fill_restore_body(ctx.root_seed)
24 => gen_valid_oi_memory_bulk_shared_atomic_xchg_restore_body()
25 => gen_valid_oi_memory_bulk_runtime_store8_mask_restore_body()
26 =>
gen_valid_oi_memory_bulk_shared_atomic_random_xchg_restore_body(
ctx.root_seed,
)
27 =>
gen_valid_oi_memory_bulk_shared_atomic_random_add_restore_body(
ctx.root_seed,
)
28 =>
gen_valid_oi_memory_bulk_shared_atomic_random_cmpxchg_restore_body(
ctx.root_seed,
)
29 =>
gen_valid_oi_memory_bulk_shared_atomic_random_sub_restore_body(
ctx.root_seed,
)
30 =>
gen_valid_oi_memory_bulk_shared_atomic_random_xor_restore_body(
ctx.root_seed,
)
31 =>
gen_valid_oi_memory_bulk_shared_atomic_random_or_restore_body(
ctx.root_seed,
)
32 =>
gen_valid_oi_memory_bulk_shared_atomic_random_and_restore_body(
ctx.root_seed,
)
33 =>
gen_valid_oi_memory_bulk_shared_atomic_localtee_add_restore_body(
ctx.root_seed,
)
42 =>
gen_valid_oi_memory_bulk_shared_atomic_localtee_xchg_restore_body(
ctx.root_seed,
)
47 =>
gen_valid_oi_memory_bulk_shared_atomic_localtee_cmpxchg_restore_body(
ctx.root_seed,
)
43 =>
gen_valid_oi_memory_bulk_shared_atomic_localtee_sub_restore_body(
ctx.root_seed,
)
44 =>
gen_valid_oi_memory_bulk_shared_atomic_localtee_xor_restore_body(
ctx.root_seed,
)
45 =>
gen_valid_oi_memory_bulk_shared_atomic_localtee_or_restore_body(
ctx.root_seed,
)
46 =>
gen_valid_oi_memory_bulk_shared_atomic_localtee_and_restore_body(
ctx.root_seed,
)
_ => gen_valid_oi_memory_bulk_direct_body()
}
} else {
gen_valid_oi_default_scalar_profile_body(case)
}
let func_type = if memory_bulk &&
(
case == 13 ||
case == 15 ||
case == 17 ||
case == 21 ||
case == 22 ||
case == 23
) {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i32()])))
} else if memory_bulk &&
(
case == 24 ||
case == 26 ||
case == 27 ||
case == 28 ||
case == 29 ||
case == 30 ||
case == 31 ||
case == 32 ||
case == 33 ||
case == 42 ||
case == 43 ||
case == 44 ||
case == 45 ||
case == 46 ||
case == 47
) {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i64()])))
} else if memory_bulk && case == 25 {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i64()])))
} else if memory_bulk && (case == 16 || case == 18 || case == 48) {
RecType::new(SubType::comp_type(CompType::func([], [ValType::i64()])))
} else {
gen_valid_precompute_void_func_type()
}
let mut mod = Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(CodeSec::new([Func::new(locals, Expr::new(body))]))
if memory_bulk {
mod = if case == 1 || case == 16 {
mod.with_mem_sec(MemSec::new([MemType::new(Limits::i64(1UL, None))]))
} else if case == 10 || case == 12 || case == 18 || case == 48 {
mod.with_mem_sec(
MemSec::new([
MemType::new(Limits::i64(1UL, None)),
MemType::new(Limits::i64(1UL, None)),
]),
)
} else if case == 6 || case == 8 || case == 9 || case == 11 || case == 17 {
mod.with_mem_sec(
MemSec::new([
MemType::new(Limits::i32(1U, None)),
MemType::new(Limits::i32(1U, None)),
]),
)
} else if case == 14 ||
case == 24 ||
case == 26 ||
case == 27 ||
case == 28 ||
case == 29 ||
case == 30 ||
case == 31 ||
case == 32 ||
case == 33 ||
case == 42 ||
case == 43 ||
case == 44 ||
case == 45 ||
case == 46 ||
case == 47 {
mod.with_mem_sec(
MemSec::new([MemType::new(Limits::i32(1U, Some(1U)), shared=true)]),
)
} else {
mod.with_mem_sec(MemSec::new([MemType::new(Limits::i32(1U, None))]))
}
if case == 2 {
mod = mod.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::i32(), true),
Expr::new([Instruction::i32_const(I32(0))]),
),
]),
)
} else if case == 13 || case == 21 || case == 22 {
let (src_addr, dst_addr) = gen_valid_oi_memory_bulk_runtime_restore_addresses(
ctx.root_seed,
)
mod = mod
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(src_addr))]),
),
b"\x07",
),
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(dst_addr))]),
),
b"\x0d",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("run"),
ExternIdx::func(FuncIdx::new(0U)),
),
]),
)
} else if case == 15 || case == 23 {
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(
ctx.root_seed,
)
mod = mod
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(dst_addr))]),
),
b"\x0d",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("run"),
ExternIdx::func(FuncIdx::new(0U)),
),
]),
)
} else if case == 16 || case == 18 || case == 48 {
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(
ctx.root_seed,
).to_int64()
let mem_idx = if case == 18 || case == 48 {
MemIdx::new(1U)
} else {
MemIdx::new(0U)
}
mod = mod.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
mem_idx,
Expr::new([Instruction::i64_const(I64(dst_addr))]),
),
b"\x0d",
),
]),
)
} else if case == 17 {
let dst_addr = gen_valid_oi_memory_bulk_fill_restore_address(
ctx.root_seed,
)
mod = mod.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(1U),
Expr::new([Instruction::i32_const(I32(dst_addr))]),
),
b"\x0d",
),
]),
)
} else if case == 14 {
mod = mod.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("run"),
ExternIdx::func(FuncIdx::new(0U)),
),
Export::new(
Name::from_string("memory"),
ExternIdx::mem(MemIdx::new(0U)),
),
]),
)
} else if case == 24 ||
case == 26 ||
case == 27 ||
case == 28 ||
case == 29 ||
case == 30 ||
case == 31 ||
case == 32 ||
case == 33 ||
case == 42 ||
case == 43 ||
case == 44 ||
case == 45 ||
case == 46 ||
case == 47 {
let addr = if case == 26 ||
case == 27 ||
case == 28 ||
case == 29 ||
case == 30 ||
case == 31 ||
case == 32 ||
case == 33 ||
case == 42 ||
case == 43 ||
case == 44 ||
case == 45 ||
case == 46 ||
case == 47 {
gen_valid_oi_memory_bulk_shared_atomic_random_address(ctx.root_seed)
} else {
64
}
mod = mod
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(addr))]),
),
b"\x2a\x00\x00\x00\x00\x00\x00\x00\x88\x77\x66\x55\x44\x33\x22\x11",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("run"),
ExternIdx::func(FuncIdx::new(0U)),
),
Export::new(
Name::from_string("memory"),
ExternIdx::mem(MemIdx::new(0U)),
),
]),
)
} else if case == 25 {
mod = mod
.with_data_sec(
DataSec::new([
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(I32(64))]),
),
b"\x0d\x00\x00\x00\x00\x00\x00\x00\x1e",
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("run"),
ExternIdx::func(FuncIdx::new(0U)),
),
]),
)
}
}
mod
}
///|
fn gen_valid_merge_locals_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(MergeLocalsForwardMultipleProfile) {
MergeLocalsForwardMultipleProfile
} else if config ==
GenValidConfig::for_profile(MergeLocalsPartialInfluenceProfile) {
MergeLocalsPartialInfluenceProfile
} else if config == GenValidConfig::for_profile(MergeLocalsReverseProfile) {
MergeLocalsReverseProfile
} else if config ==
GenValidConfig::for_profile(MergeLocalsReverseBoundaryProfile) {
MergeLocalsReverseBoundaryProfile
} else if config == GenValidConfig::for_profile(MergeLocalsControlProfile) {
MergeLocalsControlProfile
} else if config == GenValidConfig::for_profile(MergeLocalsTeeProfile) {
MergeLocalsTeeProfile
} else if config ==
GenValidConfig::for_profile(MergeLocalsMergeBoundaryProfile) {
MergeLocalsMergeBoundaryProfile
} else if config ==
GenValidConfig::for_profile(MergeLocalsTypeBoundaryProfile) {
MergeLocalsTypeBoundaryProfile
} else if config == GenValidConfig::for_profile(MergeLocalsRollbackProfile) {
MergeLocalsRollbackProfile
} else if config ==
GenValidConfig::for_profile(MergeLocalsReverseRollbackProfile) {
MergeLocalsReverseRollbackProfile
} else if config ==
GenValidConfig::for_profile(MergeLocalsNestedCopiesProfile) {
MergeLocalsNestedCopiesProfile
} else if config ==
GenValidConfig::for_profile(MergeLocalsTrivialConfusionProfile) {
MergeLocalsTrivialConfusionProfile
} else if config == GenValidConfig::for_profile(MergeLocalsUnreachableProfile) {
MergeLocalsUnreachableProfile
} else if config == GenValidConfig::for_profile(MergeLocalsLegacyEhProfile) {
MergeLocalsLegacyEhProfile
} else {
MergeLocalsForwardProfile
}
}
///|
fn gen_valid_merge_locals_i32_module(
params : Array[ValType],
results : Array[ValType],
body : Array[Instruction],
) -> Module {
let func_type = RecType::new(
SubType::comp_type(CompType::func(params, results)),
)
Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i32()]),
Expr::new(body),
),
]),
)
}
///|
fn gen_valid_merge_locals_forward_module(seed : UInt64) -> Module {
let value = (seed % 97UL).to_int() + 1
gen_valid_merge_locals_i32_module([], [ValType::i32()], [
Instruction::i32_const(I32(value)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
])
}
///|
fn gen_valid_merge_locals_forward_multiple_module(seed : UInt64) -> Module {
let value = (seed % 97UL).to_int() + 1
gen_valid_merge_locals_i32_module([], [ValType::i32()], [
Instruction::i32_const(I32(value)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
])
}
///|
fn gen_valid_merge_locals_partial_influence_module(seed : UInt64) -> Module {
let value = (seed % 89UL).to_int() + 1
let prefix : Array[Instruction] = [
Instruction::i32_const(I32(value)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
]
if seed % 2UL == 0UL {
prefix.push(Instruction::local_get(LocalIdx::new(0U)))
prefix.push(Instruction::drop())
prefix.push(Instruction::i32_const(I32(value + 1)))
prefix.push(Instruction::local_set(LocalIdx::new(0U)))
prefix.push(Instruction::local_get(LocalIdx::new(0U)))
} else {
prefix.push(Instruction::i32_const(I32(1)))
prefix.push(
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(value + 1)),
Instruction::local_set(LocalIdx::new(0U)),
],
Some([Instruction::local_get(LocalIdx::new(0U)), Instruction::drop()]),
),
)
prefix.push(Instruction::i32_const(I32(value + 2)))
}
gen_valid_merge_locals_i32_module([], [ValType::i32()], prefix)
}
///|
fn gen_valid_merge_locals_reverse_module(seed : UInt64) -> Module {
let value = (seed % 89UL).to_int() + 1
gen_valid_merge_locals_i32_module([ValType::i32()], [ValType::i32()], [
Instruction::i32_const(I32(value)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(value + 1)),
Instruction::local_set(LocalIdx::new(1U)),
],
None,
),
Instruction::local_get(LocalIdx::new(1U)),
])
}
///|
fn gen_valid_merge_locals_reverse_boundary_module(seed : UInt64) -> Module {
let value = (seed % 83UL).to_int() + 1
let body : Array[Instruction] = [
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_tee(LocalIdx::new(1U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(value))],
Some([Instruction::local_get(LocalIdx::new(1U))]),
),
Instruction::drop(),
]
if seed % 2UL == 1UL {
body.push(Instruction::i32_const(I32(value + 1)))
body.push(Instruction::local_set(LocalIdx::new(0U)))
body.push(Instruction::local_get(LocalIdx::new(0U)))
body.push(Instruction::drop())
}
gen_valid_merge_locals_i32_module([ValType::i32()], [], body)
}
///|
fn gen_valid_merge_locals_control_module(seed : UInt64) -> Module {
let value = (seed % 83UL).to_int() + 1
let control = match (seed % 3UL).to_int() {
0 =>
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
]),
)
1 =>
Instruction::if_(
BlockType::void_(),
[Instruction::local_get(LocalIdx::new(1U)), Instruction::drop()],
Some([Instruction::local_get(LocalIdx::new(1U)), Instruction::drop()]),
)
_ =>
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
]),
)
}
let condition_prefix = if (seed % 3UL).to_int() == 1 {
[Instruction::local_get(LocalIdx::new(0U))]
} else {
[]
}
let body : Array[Instruction] = [
Instruction::i32_const(I32(value)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
]
for instr in condition_prefix {
body.push(instr)
}
body.push(control)
body.push(Instruction::local_get(LocalIdx::new(2U)))
gen_valid_merge_locals_i32_module([ValType::i32()], [ValType::i32()], body)
}
///|
fn gen_valid_merge_locals_tee_module(seed : UInt64) -> Module {
let value = (seed % 79UL).to_int() + 1
gen_valid_merge_locals_i32_module([], [ValType::i32()], [
Instruction::i32_const(I32(value)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_tee(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(0U)),
])
}
///|
fn gen_valid_merge_locals_merge_boundary_module(seed : UInt64) -> Module {
let value = (seed % 73UL).to_int() + 1
gen_valid_merge_locals_i32_module([ValType::i32()], [ValType::i32()], [
Instruction::i32_const(I32(value)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(value + 1)),
Instruction::local_set(LocalIdx::new(1U)),
],
None,
),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(2U)),
])
}
///|
fn gen_valid_merge_locals_type_boundary_module() -> Module {
let base = RecType::new(SubType::new(false, [], CompType::struct_([])))
let child = RecType::new(
SubType::new(false, [TypeIdx::new(0U)], CompType::struct_([])),
)
let base_ref = ValType::ref_type(
RefType::new(true, HeapType::new(TypeIdx::new(0U))),
)
let child_ref = ValType::ref_type(
RefType::new(true, HeapType::new(TypeIdx::new(1U))),
)
let func_type = RecType::new(
SubType::comp_type(CompType::func([], [base_ref])),
)
Module::new()
.with_type_sec(TypeSec::new([base, child, func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(2U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([child_ref, base_ref]),
Expr::new([
Instruction::ref_null_type(
RefType::new(true, HeapType::new(TypeIdx::new(1U))),
),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_merge_locals_rollback_module(seed : UInt64) -> Module {
let value = (seed % 67UL).to_int() + 1
gen_valid_merge_locals_i32_module([], [ValType::i32()], [
Instruction::i32_const(I32(value)),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::i32_const(I32(value + 1)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
])
}
///|
fn gen_valid_merge_locals_reverse_rollback_module(seed : UInt64) -> Module {
let value = (seed % 61UL).to_int() + 1
let target_clobber = match (seed % 3UL).to_int() {
0 =>
[
Instruction::i32_const(I32(value + 2)),
Instruction::local_set(LocalIdx::new(0U)),
]
1 =>
[
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(value + 2)),
Instruction::local_set(LocalIdx::new(0U)),
],
None,
),
]
_ =>
[
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::local_get(LocalIdx::new(0U)), Instruction::drop()],
Some([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(value + 2)),
Instruction::local_set(LocalIdx::new(0U)),
],
None,
),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
]),
),
]),
),
]
}
let body : Array[Instruction] = [
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::if_(
BlockType::val_type(ValType::i32()),
[Instruction::i32_const(I32(value))],
Some([Instruction::local_get(LocalIdx::new(0U))]),
),
Instruction::drop(),
]
for instr in target_clobber {
body.push(instr)
}
body.push(Instruction::local_get(LocalIdx::new(0U)))
body.push(Instruction::drop())
body.push(Instruction::i32_const(I32(1)))
body.push(
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(I32(value + 3)),
Instruction::local_set(LocalIdx::new(1U)),
],
None,
),
)
body.push(Instruction::local_get(LocalIdx::new(1U)))
body.push(Instruction::drop())
gen_valid_merge_locals_i32_module([ValType::i32(), ValType::i32()], [], body)
}
///|
fn gen_valid_merge_locals_nested_copies_module(seed : UInt64) -> Module {
let (source, target) = if seed % 2UL == 0UL { (0U, 1U) } else { (1U, 0U) }
gen_valid_merge_locals_i32_module(
[ValType::i32(), ValType::i32()],
[ValType::i32()],
[
Instruction::local_get(LocalIdx::new(source)),
Instruction::local_tee(LocalIdx::new(target)),
Instruction::local_tee(LocalIdx::new(source)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(target)),
],
)
}
///|
fn gen_valid_merge_locals_trivial_confusion_module() -> Module {
gen_valid_merge_locals_i32_module(
[ValType::i32(), ValType::i32(), ValType::i32()],
[],
[
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::local_get(LocalIdx::new(2U)), Instruction::drop()],
None,
),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::br_if(LabelIdx::new(0U)),
]),
),
],
)
}
///|
fn gen_valid_merge_locals_unreachable_module() -> Module {
gen_valid_merge_locals_i32_module([], [ValType::i32()], [
Instruction::unreachable_(),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::local_tee(LocalIdx::new(0U)),
Instruction::unreachable_(),
Instruction::select(),
])
}
///|
fn gen_valid_merge_locals_legacy_eh_module(seed : UInt64) -> Module {
let func_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [ValType::i32()])),
)
let tag_type = RecType::new(SubType::comp_type(CompType::func([], [])))
let copy_body = [
Instruction::local_get(LocalIdx::new(0U)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(1U)),
]
let try_instr = match (seed % 4UL).to_int() {
0 =>
Instruction::try_(
BlockType::val_type(ValType::i32()),
Expr::new(copy_body),
[
@lib.LegacyCatch::tagged(
TagIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
],
)
1 =>
Instruction::try_(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::throw_(TagIdx::new(0U))]),
[@lib.LegacyCatch::tagged(TagIdx::new(0U), Expr::new(copy_body))],
)
2 =>
Instruction::try_(
BlockType::val_type(ValType::i32()),
Expr::new([Instruction::throw_(TagIdx::new(0U))]),
[@lib.LegacyCatch::all(Expr::new(copy_body))],
)
_ =>
Instruction::try_(
BlockType::val_type(ValType::i32()),
Expr::new([
Instruction::try_(
BlockType::val_type(ValType::i32()),
Expr::new(copy_body),
[],
delegate=Some(LabelIdx::new(0U)),
),
]),
[
@lib.LegacyCatch::tagged(
TagIdx::new(0U),
Expr::new([Instruction::i32_const(I32(0))]),
),
],
)
}
Module::new()
.with_type_sec(TypeSec::new([func_type, tag_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(1U))]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::i32()]),
Expr::new([try_instr]),
),
]),
)
}
///|
fn gen_valid_merge_locals_profile_module(ctx : GenValidContext) -> Module {
match gen_valid_merge_locals_profile_kind(ctx.config) {
MergeLocalsForwardMultipleProfile =>
gen_valid_merge_locals_forward_multiple_module(ctx.root_seed)
MergeLocalsPartialInfluenceProfile =>
gen_valid_merge_locals_partial_influence_module(ctx.root_seed)
MergeLocalsReverseProfile =>
gen_valid_merge_locals_reverse_module(ctx.root_seed)
MergeLocalsReverseBoundaryProfile =>
gen_valid_merge_locals_reverse_boundary_module(ctx.root_seed)
MergeLocalsControlProfile =>
gen_valid_merge_locals_control_module(ctx.root_seed)
MergeLocalsTeeProfile => gen_valid_merge_locals_tee_module(ctx.root_seed)
MergeLocalsMergeBoundaryProfile =>
gen_valid_merge_locals_merge_boundary_module(ctx.root_seed)
MergeLocalsTypeBoundaryProfile =>
gen_valid_merge_locals_type_boundary_module()
MergeLocalsRollbackProfile =>
gen_valid_merge_locals_rollback_module(ctx.root_seed)
MergeLocalsReverseRollbackProfile =>
gen_valid_merge_locals_reverse_rollback_module(ctx.root_seed)
MergeLocalsNestedCopiesProfile =>
gen_valid_merge_locals_nested_copies_module(ctx.root_seed)
MergeLocalsTrivialConfusionProfile =>
gen_valid_merge_locals_trivial_confusion_module()
MergeLocalsUnreachableProfile => gen_valid_merge_locals_unreachable_module()
MergeLocalsLegacyEhProfile =>
gen_valid_merge_locals_legacy_eh_module(ctx.root_seed)
_ => gen_valid_merge_locals_forward_module(ctx.root_seed)
}
}
///|
fn gen_valid_reorder_locals_profile_kind(
config : GenValidConfig,
) -> GenValidProfile {
if config == GenValidConfig::for_profile(ReorderLocalsPermutationOnlyProfile) {
ReorderLocalsPermutationOnlyProfile
} else if config ==
GenValidConfig::for_profile(ReorderLocalsFirstUseTiesProfile) {
ReorderLocalsFirstUseTiesProfile
} else if config ==
GenValidConfig::for_profile(ReorderLocalsMixedTypesProfile) {
ReorderLocalsMixedTypesProfile
} else if config ==
GenValidConfig::for_profile(ReorderLocalsReferenceTypesProfile) {
ReorderLocalsReferenceTypesProfile
} else if config ==
GenValidConfig::for_profile(ReorderLocalsUnusedTrimProfile) {
ReorderLocalsUnusedTrimProfile
} else if config ==
GenValidConfig::for_profile(ReorderLocalsStructuredProfile) {
ReorderLocalsStructuredProfile
} else if config == GenValidConfig::for_profile(ReorderLocalsLegacyEhProfile) {
ReorderLocalsLegacyEhProfile
} else if config ==
GenValidConfig::for_profile(ReorderLocalsMultiFunctionProfile) {
ReorderLocalsMultiFunctionProfile
} else if config ==
GenValidConfig::for_profile(ReorderLocalsNameRepairProfile) {
ReorderLocalsNameRepairProfile
} else {
ReorderLocalsHotSortProfile
}
}
///|
fn gen_valid_reorder_locals_i32(seed : UInt64, salt : UInt64) -> @lib.I32 {
I32(((seed ^ (salt * 2654435761UL)) % 32749UL).to_int() + 1)
}
///|
fn gen_valid_reorder_locals_i64(seed : UInt64, salt : UInt64) -> @lib.I64 {
I64(((seed ^ (salt * 11400714819323198485UL)) % 65521UL).to_int64() + 1L)
}
///|
fn gen_valid_reorder_locals_i32_types() -> Array[ValType] {
let locals : Array[ValType] = []
for _ in 0..<18 {
locals.push(ValType::i32())
}
locals
}
///|
fn gen_valid_reorder_locals_hot_sort_module(seed : UInt64) -> Module {
let func_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32(), ValType::i64()], [])),
)
Module::new()
.with_type_sec(TypeSec::new([func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new([
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 19UL)),
Instruction::local_set(LocalIdx::new(19U)),
Instruction::local_get(LocalIdx::new(19U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(19U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 4UL)),
Instruction::local_set(LocalIdx::new(4U)),
Instruction::local_get(LocalIdx::new(4U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 5UL)),
Instruction::local_tee(LocalIdx::new(5U)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_reorder_locals_permutation_only_module(seed : UInt64) -> Module {
let body : Array[Instruction] = []
for idx in 0..<18 {
body.push(
Instruction::i32_const(
gen_valid_reorder_locals_i32(seed, idx.to_uint64() + 1UL),
),
)
body.push(Instruction::local_set(LocalIdx::new(idx.to_uint())))
body.push(Instruction::local_get(LocalIdx::new(idx.to_uint())))
body.push(Instruction::drop())
}
for _ in 0..<3 {
body.push(Instruction::local_get(LocalIdx::new(17U)))
body.push(Instruction::drop())
}
for _ in 0..<2 {
body.push(Instruction::local_get(LocalIdx::new(15U)))
body.push(Instruction::drop())
}
body.push(Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 33UL)))
body.push(Instruction::local_tee(LocalIdx::new(16U)))
body.push(Instruction::drop())
Module::new()
.with_type_sec(TypeSec::new([gen_valid_precompute_void_func_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new(body),
),
]),
)
}
///|
fn gen_valid_reorder_locals_first_use_ties_module(seed : UInt64) -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_precompute_void_func_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new([
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 17UL)),
Instruction::local_set(LocalIdx::new(17U)),
Instruction::local_get(LocalIdx::new(17U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 2UL)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 9UL)),
Instruction::local_set(LocalIdx::new(9U)),
Instruction::local_get(LocalIdx::new(9U)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_reorder_locals_mixed_types_module(seed : UInt64) -> Module {
let locals = [
ValType::i32(),
ValType::f64(),
ValType::i64(),
ValType::f32(),
ValType::i32(),
ValType::f64(),
ValType::i64(),
ValType::f32(),
ValType::i32(),
ValType::f64(),
ValType::i64(),
ValType::f32(),
ValType::i32(),
ValType::f64(),
ValType::i64(),
ValType::f32(),
ValType::i32(),
ValType::f64(),
]
Module::new()
.with_type_sec(TypeSec::new([gen_valid_precompute_void_func_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(locals),
Expr::new([
Instruction::f64_const(F64((seed % 97UL).to_int().to_double() + 0.25)),
Instruction::local_set(LocalIdx::new(17U)),
Instruction::local_get(LocalIdx::new(17U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(17U)),
Instruction::drop(),
Instruction::i64_const(gen_valid_reorder_locals_i64(seed, 2UL)),
Instruction::local_set(LocalIdx::new(2U)),
Instruction::local_get(LocalIdx::new(2U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 16UL)),
Instruction::local_set(LocalIdx::new(16U)),
Instruction::local_get(LocalIdx::new(16U)),
Instruction::drop(),
Instruction::f32_const(
F32(Float::from_double((seed % 53UL).to_int().to_double() + 0.5)),
),
Instruction::local_tee(LocalIdx::new(3U)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_reorder_locals_reference_types_module(seed : UInt64) -> Module {
let struct_type = RecType::new(SubType::comp_type(CompType::struct_([])))
let func_type = gen_valid_precompute_void_func_type()
let heap = HeapType::new(TypeIdx::new(0U))
let nullable = ValType::ref_type(RefType::new(true, heap))
let nonnullable = ValType::ref_type(RefType::new(false, heap))
let locals = Array::make(18, ValType::i32())
locals[0] = nullable
locals[17] = nonnullable
Module::new()
.with_type_sec(TypeSec::new([struct_type, func_type]))
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(locals),
Expr::new([
Instruction::struct_new_default(TypeIdx::new(0U)),
Instruction::local_set(LocalIdx::new(17U)),
Instruction::local_get(LocalIdx::new(17U)),
Instruction::drop(),
Instruction::local_get(LocalIdx::new(17U)),
Instruction::drop(),
Instruction::ref_null(heap),
Instruction::local_set(LocalIdx::new(0U)),
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 1UL)),
Instruction::local_set(LocalIdx::new(1U)),
]),
),
]),
)
}
///|
fn gen_valid_reorder_locals_unused_trim_module(seed : UInt64) -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_precompute_void_func_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U), TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new([
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 16UL)),
Instruction::local_set(LocalIdx::new(16U)),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 4UL)),
Instruction::local_set(LocalIdx::new(4U)),
Instruction::local_get(LocalIdx::new(4U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 5UL)),
Instruction::local_tee(LocalIdx::new(5U)),
Instruction::drop(),
]),
),
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new([Instruction::nop()]),
),
]),
)
}
///|
fn gen_valid_reorder_locals_structured_module(seed : UInt64) -> Module {
let hot = gen_valid_reorder_locals_i32(seed, 17UL)
Module::new()
.with_type_sec(TypeSec::new([gen_valid_precompute_void_func_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new([
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::loop_(
BlockType::void_(),
Expr::new([
Instruction::local_get(LocalIdx::new(17U)),
Instruction::drop(),
]),
),
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[
Instruction::i32_const(
gen_valid_reorder_locals_i32(seed, 3UL),
),
Instruction::local_set(LocalIdx::new(3U)),
],
Some([
Instruction::i32_const(
gen_valid_reorder_locals_i32(seed, 4UL),
),
Instruction::local_tee(LocalIdx::new(4U)),
Instruction::drop(),
]),
),
Instruction::try_table(
BlockType::void_(),
[],
Expr::new([
Instruction::i32_const(hot),
Instruction::local_set(LocalIdx::new(17U)),
Instruction::local_get(LocalIdx::new(17U)),
Instruction::drop(),
]),
),
]),
),
]),
),
]),
)
}
///|
fn gen_valid_reorder_locals_legacy_eh_module(seed : UInt64) -> Module {
let tag_type = RecType::new(SubType::comp_type(CompType::func([], [])))
let func_type = gen_valid_precompute_void_func_type()
Module::new()
.with_type_sec(TypeSec::new([tag_type, func_type]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(0U))]))
.with_func_sec(FuncSec::new([TypeIdx::new(1U), TypeIdx::new(1U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new([
Instruction::try_(
BlockType::void_(),
Expr::new([
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 16UL)),
Instruction::local_set(LocalIdx::new(16U)),
]),
[
@lib.LegacyCatch::tagged(
TagIdx::new(0U),
Expr::new([
Instruction::local_get(LocalIdx::new(3U)),
Instruction::drop(),
]),
),
@lib.LegacyCatch::all(
Expr::new([
Instruction::i32_const(
gen_valid_reorder_locals_i32(seed, 4UL),
),
Instruction::local_tee(LocalIdx::new(4U)),
Instruction::drop(),
]),
),
],
),
]),
),
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new([
Instruction::try_(
BlockType::void_(),
Expr::new([
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 17UL)),
Instruction::local_set(LocalIdx::new(17U)),
Instruction::local_get(LocalIdx::new(17U)),
Instruction::drop(),
]),
[],
delegate=Some(LabelIdx::new(0U)),
),
]),
),
]),
)
}
///|
fn gen_valid_reorder_locals_multi_function_module(seed : UInt64) -> Module {
let import_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [ValType::i32()])),
)
let two_param_type = RecType::new(
SubType::comp_type(CompType::func([ValType::i64(), ValType::i32()], [])),
)
let void_type = gen_valid_precompute_void_func_type()
Module::new()
.with_type_sec(TypeSec::new([import_type, two_param_type, void_type]))
.with_import_sec(
ImportSec::new([
Import::new(
Name::from_string("env"),
Name::from_string("identity"),
ExternType::func(TypeIdx::new(0U)),
),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(1U), TypeIdx::new(2U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types([ValType::i32(), ValType::f64(), ValType::i64()]),
Expr::new([
Instruction::local_get(LocalIdx::new(0U)),
Instruction::drop(),
Instruction::i64_const(gen_valid_reorder_locals_i64(seed, 4UL)),
Instruction::local_set(LocalIdx::new(4U)),
Instruction::local_get(LocalIdx::new(4U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 2UL)),
Instruction::local_set(LocalIdx::new(2U)),
]),
),
Func::new(
Locals::from_types([ValType::i64(), ValType::i32()]),
Expr::new([
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 1UL)),
Instruction::local_set(LocalIdx::new(1U)),
Instruction::local_get(LocalIdx::new(1U)),
Instruction::drop(),
Instruction::i64_const(gen_valid_reorder_locals_i64(seed, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
]),
),
]),
)
.with_name_sec(
NameSec::new(
local_names=Some(
IndirectNameMap::new([
IndirectNameAssoc::new(
0U,
NameMap::new([NameAssoc::new(0U, Name::new("import_param"))]),
),
IndirectNameAssoc::new(
1U,
NameMap::new([
NameAssoc::new(0U, Name::new("lhs")),
NameAssoc::new(1U, Name::new("rhs")),
NameAssoc::new(2U, Name::new("cold")),
NameAssoc::new(4U, Name::new("hot")),
]),
),
IndirectNameAssoc::new(
2U,
NameMap::new([
NameAssoc::new(0U, Name::new("wide")),
NameAssoc::new(1U, Name::new("hot")),
]),
),
]),
),
),
)
}
///|
fn gen_valid_reorder_locals_name_repair_module(seed : UInt64) -> Module {
Module::new()
.with_type_sec(TypeSec::new([gen_valid_precompute_void_func_type()]))
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_code_sec(
CodeSec::new([
Func::new(
Locals::from_types(gen_valid_reorder_locals_i32_types()),
Expr::new([
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 16UL)),
Instruction::local_set(LocalIdx::new(16U)),
Instruction::local_get(LocalIdx::new(16U)),
Instruction::drop(),
Instruction::i32_const(gen_valid_reorder_locals_i32(seed, 0UL)),
Instruction::local_set(LocalIdx::new(0U)),
]),
),
]),
)
.with_name_sec(
NameSec::new(
func_names=Some(NameMap::new([NameAssoc::new(0U, Name::new("rl"))])),
local_names=Some(
IndirectNameMap::new([
IndirectNameAssoc::new(
0U,
NameMap::new([
NameAssoc::new(0U, Name::new("cold_write")),
NameAssoc::new(1U, Name::new("unused_one")),
NameAssoc::new(16U, Name::new("hot_named")),
]),
),
]),
),
),
)
}
///|
fn gen_valid_reorder_locals_profile_module(ctx : GenValidContext) -> Module {
match gen_valid_reorder_locals_profile_kind(ctx.config) {
ReorderLocalsPermutationOnlyProfile =>
gen_valid_reorder_locals_permutation_only_module(ctx.root_seed)
ReorderLocalsFirstUseTiesProfile =>
gen_valid_reorder_locals_first_use_ties_module(ctx.root_seed)
ReorderLocalsMixedTypesProfile =>
gen_valid_reorder_locals_mixed_types_module(ctx.root_seed)
ReorderLocalsReferenceTypesProfile =>
gen_valid_reorder_locals_reference_types_module(ctx.root_seed)
ReorderLocalsUnusedTrimProfile =>
gen_valid_reorder_locals_unused_trim_module(ctx.root_seed)
ReorderLocalsStructuredProfile =>
gen_valid_reorder_locals_structured_module(ctx.root_seed)
ReorderLocalsLegacyEhProfile =>
gen_valid_reorder_locals_legacy_eh_module(ctx.root_seed)
ReorderLocalsMultiFunctionProfile =>
gen_valid_reorder_locals_multi_function_module(ctx.root_seed)
ReorderLocalsNameRepairProfile =>
gen_valid_reorder_locals_name_repair_module(ctx.root_seed)
_ => gen_valid_reorder_locals_hot_sort_module(ctx.root_seed)
}
}
///|
fn gen_valid_die_void_type() -> RecType {
RecType::new(SubType::comp_type(CompType::func([], [])))
}
///|
fn gen_valid_duplicate_import_elimination_functions_module() -> Module {
let i32_consumer = RecType::new(
SubType::comp_type(CompType::func([ValType::i32()], [])),
)
Module::new()
.with_type_sec(TypeSec::new([i32_consumer, gen_valid_die_void_type()]))
.with_import_sec(
ImportSec::new([
Import::new(
Name::from_string("env"),
Name::from_string("die.dup"),
ExternType::func(TypeIdx::new(0U)),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.dup"),
ExternType::func(TypeIdx::new(1U)),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.dup"),
ExternType::func(TypeIdx::new(1U)),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.unique"),
ExternType::func(TypeIdx::new(1U)),
),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_start_sec(StartSec::new(FuncIdx::new(2U)))
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("die.export"),
ExternIdx::func(FuncIdx::new(2U)),
),
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(4U))),
]),
)
.with_elem_sec(
ElemSec::new([
Elem::new(ElemMode::declarative(), ElemKind::funcs([FuncIdx::new(2U)])),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::i32_const(I32(7)),
Instruction::call(FuncIdx::new(0U)),
Instruction::call(FuncIdx::new(2U)),
Instruction::block(
BlockType::void_(),
Expr::new([Instruction::call(FuncIdx::new(2U))]),
),
Instruction::loop_(
BlockType::void_(),
Expr::new([Instruction::call(FuncIdx::new(2U))]),
),
Instruction::i32_const(I32(1)),
Instruction::if_(
BlockType::void_(),
[Instruction::call(FuncIdx::new(2U))],
Some([Instruction::ref_func(FuncIdx::new(2U)), Instruction::drop()]),
),
Instruction::ref_func(FuncIdx::new(2U)),
Instruction::drop(),
Instruction::call(FuncIdx::new(3U)),
Instruction::return_call(FuncIdx::new(2U)),
]),
),
]),
)
}
///|
fn gen_valid_duplicate_import_elimination_identity_module(
seed : UInt64,
) -> Module {
let imports : Array[Import] = []
let mut duplicate_idx = 1U
match (seed % 5UL).to_int() {
0 => {
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
duplicate_idx = 2U
}
1 => {
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(0U)),
),
)
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
duplicate_idx = 2U
}
2 => {
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
imports.push(
Import::new(
Name::from_string("other"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
}
3 => {
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.other"),
ExternType::func(TypeIdx::new(1U)),
),
)
}
_ => {
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(1U)),
),
)
imports.push(
Import::new(
Name::from_string("env"),
Name::from_string("die.identity"),
ExternType::func(TypeIdx::new(2U)),
),
)
}
}
let defined_idx = imports.length().reinterpret_as_uint()
Module::new()
.with_type_sec(
TypeSec::new([
RecType::new(SubType::comp_type(CompType::func([ValType::i32()], []))),
gen_valid_die_void_type(),
gen_valid_die_void_type(),
]),
)
.with_import_sec(ImportSec::new(imports))
.with_func_sec(FuncSec::new([TypeIdx::new(1U)]))
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("run"),
ExternIdx::func(FuncIdx::new(defined_idx)),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::call(FuncIdx::new(duplicate_idx))]),
),
]),
)
}
///|
fn gen_valid_duplicate_import_elimination_module_code_module() -> Module {
let funcref = RefType::new(true, HeapType::abs(AbsHeapType::func()))
Module::new()
.with_type_sec(TypeSec::new([gen_valid_die_void_type()]))
.with_import_sec(
ImportSec::new([
Import::new(
Name::from_string("env"),
Name::from_string("die.module-code"),
ExternType::func(TypeIdx::new(0U)),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.module-code"),
ExternType::func(TypeIdx::new(0U)),
),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_table_sec(
TableSec::new([
Table::new(
TableType::new(funcref, Limits::i32(1U, None)),
Some(Expr::new([Instruction::ref_func(FuncIdx::new(1U))])),
),
]),
)
.with_global_sec(
GlobalSec::new([
Global::new(
GlobalType::new(ValType::funcref(), false),
Expr::new([Instruction::ref_func(FuncIdx::new(1U))]),
),
]),
)
.with_export_sec(
ExportSec::new([
Export::new(
Name::from_string("die.export"),
ExternIdx::func(FuncIdx::new(1U)),
),
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
]),
)
.with_start_sec(StartSec::new(FuncIdx::new(1U)))
.with_elem_sec(
ElemSec::new([
Elem::new(
ElemMode::declarative(),
ElemKind::funcs([FuncIdx::new(0U), FuncIdx::new(1U)]),
),
Elem::new(
ElemMode::declarative(),
ElemKind::func_exprs([
Expr::new([Instruction::ref_func(FuncIdx::new(1U))]),
]),
),
Elem::new(
ElemMode::passive(),
ElemKind::typed_exprs(funcref, [
Expr::new([Instruction::ref_func(FuncIdx::new(1U))]),
]),
),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([Instruction::call(FuncIdx::new(1U))]),
),
]),
)
}
///|
fn gen_valid_duplicate_import_elimination_legacy_eh_module(
seed : UInt64,
) -> Module {
let duplicate = FuncIdx::new(1U)
let tag = TagIdx::new(0U)
let body = match (seed % 5UL).to_int() {
0 =>
[
Instruction::try_(
BlockType::void_(),
Expr::new([Instruction::call(duplicate)]),
[@lib.LegacyCatch::tagged(tag, Expr::new([Instruction::nop()]))],
),
]
1 =>
[
Instruction::try_(
BlockType::void_(),
Expr::new([Instruction::throw_(tag)]),
[
@lib.LegacyCatch::tagged(
tag,
Expr::new([Instruction::call(duplicate)]),
),
],
),
]
2 =>
[
Instruction::try_(
BlockType::void_(),
Expr::new([Instruction::throw_(tag)]),
[
@lib.LegacyCatch::all(
Expr::new([Instruction::ref_func(duplicate), Instruction::drop()]),
),
],
),
]
3 =>
[
Instruction::try_(
BlockType::void_(),
Expr::new([
Instruction::try_(
BlockType::void_(),
Expr::new([Instruction::call(duplicate)]),
[],
delegate=Some(LabelIdx::new(0U)),
),
]),
[@lib.LegacyCatch::tagged(tag, Expr::new([Instruction::nop()]))],
),
]
_ =>
[
Instruction::block(
BlockType::void_(),
Expr::new([
Instruction::try_table(
BlockType::void_(),
[Catch::new(tag, LabelIdx::new(0U))],
Expr::new([Instruction::call(duplicate)]),
),
]),
),
]
}
Module::new()
.with_type_sec(
TypeSec::new([gen_valid_die_void_type(), gen_valid_die_void_type()]),
)
.with_import_sec(
ImportSec::new([
Import::new(
Name::from_string("env"),
Name::from_string("die.eh"),
ExternType::func(TypeIdx::new(0U)),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.eh"),
ExternType::func(TypeIdx::new(0U)),
),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_tag_sec(TagSec::new([TagType::new(TypeIdx::new(1U))]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(2U))),
]),
)
.with_code_sec(CodeSec::new([Func::new(Locals::empty(), Expr::new(body))]))
}
///|
fn gen_valid_duplicate_import_elimination_nonfunction_module() -> Module {
let table_type = TableType::new(
RefType::new(true, HeapType::abs(AbsHeapType::func())),
Limits::i32(1U, None),
)
let mem_type = MemType::new(Limits::i32(1U, None))
let global_type = GlobalType::new(ValType::i32(), false)
let tag_type = TagType::new(TypeIdx::new(0U))
Module::new()
.with_type_sec(TypeSec::new([gen_valid_die_void_type()]))
.with_import_sec(
ImportSec::new([
Import::new(
Name::from_string("env"),
Name::from_string("die.global"),
ExternType::global(global_type),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.global"),
ExternType::global(global_type),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.table"),
ExternType::table(table_type),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.table"),
ExternType::table(table_type),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.memory"),
ExternType::mem(mem_type),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.memory"),
ExternType::mem(mem_type),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.tag"),
ExternType::tag(tag_type),
),
Import::new(
Name::from_string("env"),
Name::from_string("die.tag"),
ExternType::tag(tag_type),
),
]),
)
.with_func_sec(FuncSec::new([TypeIdx::new(0U)]))
.with_export_sec(
ExportSec::new([
Export::new(Name::from_string("run"), ExternIdx::func(FuncIdx::new(0U))),
]),
)
.with_code_sec(
CodeSec::new([
Func::new(
Locals::empty(),
Expr::new([
Instruction::global_get(GlobalIdx::new(1U)),
Instruction::drop(),
Instruction::table_size(TableIdx::new(1U)),
Instruction::drop(),
Instruction::memory_size(MemIdx::new(1U)),
Instruction::drop(),
]),
),
]),
)
}
///|
fn gen_valid_duplicate_import_elimination_profile_module(
ctx : GenValidContext,
) -> Module {
let config = ctx.config
if config ==
GenValidConfig::for_profile(DuplicateImportEliminationIdentityProfile) {
gen_valid_duplicate_import_elimination_identity_module(ctx.root_seed)
} else if config ==
GenValidConfig::for_profile(DuplicateImportEliminationModuleCodeProfile) {
gen_valid_duplicate_import_elimination_module_code_module()
} else if config ==
GenValidConfig::for_profile(DuplicateImportEliminationLegacyEhProfile) {
gen_valid_duplicate_import_elimination_legacy_eh_module(ctx.root_seed)
} else if config ==
GenValidConfig::for_profile(DuplicateImportEliminationNonfunctionProfile) {
gen_valid_duplicate_import_elimination_nonfunction_module()
} else {
gen_valid_duplicate_import_elimination_functions_module()
}
}
///|
fn gen_valid_module_once_with_context(ctx : GenValidContext) -> Module {
let config = ctx.config
if config == gen_valid_heap2local_owner_updates_config() {
return gen_valid_heap2local_owner_updates_module(ctx.root_seed)
}
if gen_valid_is_engine_tiering_config(config) {
return gen_valid_engine_tiering_profile_module(ctx)
}
if config == gen_valid_campaign_memory64_config() {
return gen_valid_campaign_memory64_module(ctx)
}
if config == gen_valid_campaign_eh_control_config() {
return gen_valid_campaign_eh_control_module(ctx)
}
if gen_valid_is_campaign_gc_refs_config(config) {
return gen_valid_campaign_gc_refs_module(ctx)
}
if config == gen_valid_campaign_simd_numeric_config() {
return gen_valid_campaign_simd_numeric_module(ctx)
}
if config == gen_valid_campaign_call_topology_config() {
return gen_valid_campaign_call_topology_module(ctx)
}
if config == gen_valid_campaign_segment_state_config() {
return gen_valid_campaign_segment_state_module(ctx)
}
if gen_valid_is_engine_state_profile_config(config) {
return gen_valid_engine_state_profile_module(ctx)
}
if gen_valid_is_rume_profile_config(config) {
return gen_valid_rume_profile_module(ctx)
}
if gen_valid_is_global_refining_profile_config(config) {
return gen_valid_global_refining_profile_module(ctx)
}
if gen_valid_is_reorder_globals_profile_config(config) {
return gen_valid_reorder_globals_profile_module(ctx)
}
if gen_valid_is_directize_profile_config(config) {
return gen_valid_directize_profile_module(ctx)
}
if gen_valid_is_flatten_profile_config(config) {
return gen_valid_flatten_profile_module(config)
}
if gen_valid_is_merge_blocks_profile_config(config) {
return gen_valid_merge_blocks_profile_module(config)
}
if gen_valid_is_code_folding_profile_config(config) {
return gen_valid_code_folding_profile_module(config)
}
if gen_valid_is_duplicate_import_elimination_profile_config(config) {
return gen_valid_duplicate_import_elimination_profile_module(ctx)
}
if gen_valid_is_constraint_profile_config(config) {
return gen_valid_constraint_profile_module(ctx)
}
if config == gen_valid_compact_imports_config() {
return gen_valid_compact_imports_module(ctx)
}
if config == gen_valid_descriptor_branches_config() {
return gen_valid_descriptor_branches_module(ctx)
}
if config == gen_valid_atomic_orders_config() {
return gen_valid_atomic_orders_module(ctx)
}
if config == gen_valid_waitqueue_config() {
return gen_valid_waitqueue_module(ctx)
}
if config == gen_valid_array_memory_config() {
return gen_valid_array_memory_module(ctx)
}
if gen_valid_is_dae2_profile_config(config) {
return gen_valid_dae2_profile_module(ctx)
}
if gen_valid_is_undersampled_pass_profile_config(config) {
return gen_valid_undersampled_pass_profile_module(ctx)
}
if gen_valid_is_msf_profile_config(config) {
return gen_valid_msf_profile_module(ctx)
}
if gen_valid_is_merge_locals_profile_config(config) {
return gen_valid_merge_locals_profile_module(ctx)
}
if gen_valid_is_reorder_locals_profile_config(config) {
return gen_valid_reorder_locals_profile_module(ctx)
}
if gen_valid_is_simplify_locals_family_profile_config(config) {
return gen_valid_simplify_locals_family_profile_module(ctx.root_seed)
}
if gen_valid_is_oi_trigger_profile_config(config) {
return gen_valid_oi_trigger_profile_module(ctx)
}
if gen_valid_is_gsi_desc_cast_profile_config(config) {
return gen_valid_gsi_desc_cast_profile_module(config)
}
if gen_valid_is_precompute_profile_config(config) {
return gen_valid_precompute_profile_module(config)
}
if gen_valid_is_inlining_optimizing_profile_config(config) {
return gen_valid_inlining_optimizing_profile_module(config)
}
if gen_valid_is_sgo_profile_config(config) {
return gen_valid_sgo_profile_module(config)
}
if gen_valid_is_pgg_profile_config(config) {
return gen_valid_pgg_profile_module(ctx)
}
if gen_valid_is_once_reduction_profile_config(config) {
return gen_valid_once_reduction_profile_module()
}
if gen_valid_is_vacuum_profile_config(config) {
return gen_valid_vacuum_profile_module(ctx)
}
if gen_valid_is_rse_profile_config(config) {
return gen_valid_rse_profile_module(config)
}
if gen_valid_is_dae_unused_params_profile_config(config) {
return gen_valid_dae_unused_params_profile_module()
}
if gen_valid_is_dae_effectful_args_profile_config(config) {
return gen_valid_dae_effectful_args_profile_module()
}
if gen_valid_is_dae_constant_args_profile_config(config) {
return gen_valid_dae_constant_args_profile_module()
}
if gen_valid_is_dae_unused_returns_profile_config(config) {
return gen_valid_dae_unused_returns_profile_module()
}
if gen_valid_is_dae_arg_type_refinement_profile_config(config) {
return gen_valid_dae_arg_type_refinement_profile_module()
}
if gen_valid_is_dae_return_type_refinement_profile_config(config) {
return gen_valid_dae_return_type_refinement_profile_module()
}
if gen_valid_is_dae_unseen_call_boundary_profile_config(config) {
return gen_valid_dae_unseen_call_boundary_profile_module()
}
if gen_valid_is_dae_tail_call_boundary_profile_config(config) {
return gen_valid_dae_tail_call_boundary_profile_module()
}
if gen_valid_is_dae_localization_profile_config(config) {
return gen_valid_dae_localization_profile_module()
}
if gen_valid_is_dae_convergence_profile_config(config) {
return gen_valid_dae_convergence_profile_module()
}
if gen_valid_is_dae_optimizing_profile_config(config) {
return gen_valid_dae_optimizing_profile_module(ctx)
}
if gen_valid_is_pick_load_signs_profile_config(config) {
return gen_valid_pick_load_signs_profile_module(config)
}
if gen_valid_is_code_pushing_profile_config(config) {
return gen_valid_code_pushing_profile_module(config)
}
if gen_valid_is_remove_unused_brs_focused_config(config) {
return gen_valid_remove_unused_brs_profile_module(ctx)
}
if gen_valid_is_tuple_optimization_profile_config(config) {
return gen_valid_tuple_optimization_profile_module(config)
}
if config == gen_valid_tuple_alias_captures_config() {
return gen_valid_tuple_alias_captures_module(ctx.root_seed)
}
if gen_valid_is_dead_code_elimination_profile_config(config) {
return gen_valid_dead_code_elimination_profile_module(config)
}
if gen_valid_is_memory_packing_profile_config(config) {
return gen_valid_memory_packing_profile_module(ctx)
}
let import_budget = gen_valid_choose_optional_count_with_coverage_floor(
ctx,
config.features.allow_imports,
config.max_imports,
config.section_bias.imports_percent,
if config.features.allow_const_expr_variants &&
config.features.allow_globals {
6
} else {
5
},
)
let mut import_plan : GenValidImportPlan = {
func_count: 0,
table_count: 0,
mem_count: 0,
global_count: 0,
tag_count: 0,
}
let mut remaining_imports = import_budget
if ctx.config.mode == CoverageForced {
if remaining_imports > 0 {
import_plan = { ..import_plan, func_count: 1, }
remaining_imports -= 1
}
if config.features.allow_tables && remaining_imports > 0 {
import_plan = { ..import_plan, table_count: 1, }
remaining_imports -= 1
}
if config.features.allow_mems && remaining_imports > 0 {
import_plan = { ..import_plan, mem_count: 1, }
remaining_imports -= 1
}
if config.features.allow_globals && remaining_imports > 0 {
import_plan = { ..import_plan, global_count: 1, }
remaining_imports -= 1
}
if config.features.allow_tags && remaining_imports > 0 {
import_plan = { ..import_plan, tag_count: 1, }
remaining_imports -= 1
}
if config.features.allow_const_expr_variants &&
config.features.allow_globals &&
remaining_imports > 0 {
import_plan = {
..import_plan,
global_count: import_plan.global_count + 1,
}
remaining_imports -= 1
}
if config.features.allow_const_expr_variants &&
config.features.allow_globals &&
remaining_imports > 0 {
import_plan = {
..import_plan,
global_count: import_plan.global_count + 1,
}
remaining_imports -= 1
}
if config.features.allow_const_expr_variants &&
config.features.allow_globals &&
remaining_imports > 0 {
import_plan = {
..import_plan,
global_count: import_plan.global_count + 1,
}
remaining_imports -= 1
}
}
let import_choice_count = 1 +
gen_valid_bool_count(config.features.allow_tables) +
gen_valid_bool_count(config.features.allow_mems) +
gen_valid_bool_count(config.features.allow_globals) +
gen_valid_bool_count(config.features.allow_tags)
while remaining_imports > 0 {
let mut choice = ctx.random_int_from(
ModuleTopologyStream,
import_choice_count,
)
if choice == 0 {
import_plan = { ..import_plan, func_count: import_plan.func_count + 1, }
} else {
choice -= 1
if config.features.allow_tables && choice == 0 {
import_plan = {
..import_plan,
table_count: import_plan.table_count + 1,
}
} else {
if config.features.allow_tables {
choice -= 1
}
if config.features.allow_mems && choice == 0 {
import_plan = { ..import_plan, mem_count: import_plan.mem_count + 1, }
} else {
if config.features.allow_mems {
choice -= 1
}
if config.features.allow_globals && choice == 0 {
import_plan = {
..import_plan,
global_count: import_plan.global_count + 1,
}
} else {
import_plan = {
..import_plan,
tag_count: import_plan.tag_count + 1,
}
}
}
}
}
remaining_imports -= 1
}
let import_func_count = import_plan.func_count
let import_table_count = import_plan.table_count
let import_mem_count = import_plan.mem_count
let import_global_count = import_plan.global_count
let import_tag_count = import_plan.tag_count
let defined_func_count = gen_valid_choose_defined_func_count(ctx)
let defined_table_count = gen_valid_choose_optional_count_with_coverage_floor_from(
ctx,
TableStream,
config.features.allow_tables,
config.max_tables,
config.section_bias.tables_percent,
if config.features.allow_table_limit_variants &&
config.features.allow_ref_types &&
config.features.allow_const_expr_variants &&
config.features.allow_v128 {
6
} else if config.features.allow_table_limit_variants &&
config.features.allow_ref_types &&
config.features.allow_const_expr_variants {
5
} else if config.features.allow_table_limit_variants &&
config.features.allow_ref_types {
4
} else {
1
},
)
let defined_mem_count = gen_valid_choose_optional_count_with_coverage_floor_from(
ctx,
MemoryStream,
config.features.allow_mems,
config.max_mems,
config.section_bias.mems_percent,
if config.features.allow_memory_limit_variants ||
config.features.allow_shared_memories ||
config.features.allow_memory64 {
2
} else {
1
},
)
let defined_global_count = gen_valid_choose_optional_count_with_coverage_floor_from(
ctx,
GlobalStream,
config.features.allow_globals,
config.max_globals,
config.section_bias.globals_percent,
if config.features.allow_const_expr_variants {
6
} else {
1
},
)
let defined_tag_count = gen_valid_choose_optional_count_from(
ctx,
TagStream,
config.features.allow_tags,
config.max_tags,
config.section_bias.tags_percent,
)
let total_table_count = import_table_count + defined_table_count
let total_mem_count = import_mem_count + defined_mem_count
let total_global_count = import_global_count + defined_global_count
let total_tag_count = import_tag_count + defined_tag_count
let elem_count = if total_table_count > 0 {
gen_valid_choose_optional_count_with_coverage_floor_from(
ctx,
ElemStream,
config.features.allow_elems,
config.max_elems,
config.section_bias.elems_percent,
if ctx.config.mode == CoverageForced &&
config.features.allow_const_expr_variants &&
config.features.allow_ref_types {
6
} else if ctx.config.mode == CoverageForced {
4
} else {
3
},
)
} else {
0
}
let data_count = if total_mem_count > 0 {
gen_valid_choose_optional_count_with_coverage_floor_from(
ctx,
DataStream,
config.features.allow_datas,
config.max_datas,
config.section_bias.datas_percent,
if ctx.config.mode == CoverageForced &&
config.features.allow_const_expr_variants {
4
} else {
2
},
)
} else {
0
}
let has_start = config.features.allow_start &&
(
ctx.config.mode == CoverageForced ||
gen_valid_roll_percent_from(
ctx,
StartStream,
config.section_bias.start_percent,
)
)
let total_type_users = import_func_count +
defined_func_count +
total_tag_count
let max_type_defs = if gen_valid_clamp_non_negative(config.max_type_defs) <= 0 {
1
} else {
gen_valid_clamp_non_negative(config.max_type_defs)
}
let reserved_gc_slots = if config.features.allow_heap2local_body_generator &&
(
config == GenValidConfig::for_profile(Heap2LocalArrayProfile) ||
config == GenValidConfig::for_profile(Heap2LocalAllProfile)
) {
// The first array follows the normal struct and packed struct definitions.
3
} else if config.features.allow_heap2local_body_generator &&
(
config == GenValidConfig::for_profile(Heap2LocalStructProfile) ||
config == GenValidConfig::for_profile(Heap2LocalRefProfile)
) {
1
} else if ctx.config.mode == Natural &&
config.features.allow_ref_types &&
max_type_defs > 1 {
gen_valid_min_int(3, max_type_defs - 1)
} else {
0
}
let func_type_cap = if max_type_defs - reserved_gc_slots > 1 {
max_type_defs - reserved_gc_slots
} else {
1
}
let mut func_type_count = if ctx.config.mode == CoverageForced &&
total_type_users > 1 {
1 +
ctx.random_int_from(
TypeStream,
gen_valid_min_int(func_type_cap, total_type_users - 1),
)
} else {
1 + ctx.random_int_from(TypeStream, func_type_cap)
}
let typed_body_min_func_types = if gen_valid_is_control_heavy_config(
ctx.config,
) {
4
} else if ctx.config.features.allow_typed_body_generator &&
ctx.config.features.allow_v128 {
3
} else {
2
}
if ctx.config.features.allow_typed_body_generator &&
func_type_cap >= typed_body_min_func_types &&
func_type_count < typed_body_min_func_types {
func_type_count = typed_body_min_func_types
} else if ctx.config.features.allow_typed_body_generator &&
func_type_cap > 1 &&
func_type_count < 2 {
func_type_count = 2
}
if ctx.config.features.allow_heap_store_optimization_body_generator &&
func_type_cap > 1 &&
func_type_count < 2 {
func_type_count = 2
}
let remaining_type_budget = max_type_defs - func_type_count
let (gc_type_defs, gc_type_plan) = gen_valid_gc_type_defs(
ctx, func_type_count, remaining_type_budget,
)
let payload_tag_type_idx = if ctx.config.mode == CoverageForced &&
config.features.allow_tags &&
total_tag_count > 1 {
Some(
TypeIdx::new(
(func_type_count + gen_valid_rec_types_flat_count(gc_type_defs)).reinterpret_as_uint(),
),
)
} else {
None
}
let type_defs : Array[RecType] = []
let type_params : Array[Array[ValType]] = []
let type_results : Array[Array[ValType]] = []
let exact_result_slot = if gc_type_plan.exact_ref_types.is_empty() {
None
} else if has_start || total_tag_count > 0 {
if func_type_count > 1 {
Some(func_type_count - 1)
} else {
None
}
} else {
Some(func_type_count - 1)
}
for i = 0; i < func_type_count; i = i + 1 {
let params = if i == 0 && (has_start || total_tag_count > 0) {
[]
} else if ctx.config.features.allow_heap_store_optimization_body_generator &&
i == 1 {
[]
} else if ctx.config.features.allow_typed_body_generator && i == 1 {
[]
} else if ctx.config.features.allow_typed_body_generator &&
ctx.config.features.allow_v128 &&
i == 2 {
[ValType::v128()]
} else if gen_valid_is_control_heavy_config(ctx.config) && i == 3 {
[ValType::i32(), ValType::i64()]
} else if gen_valid_is_ssa_nomerge_family_config(ctx.config) && i == 0 {
[ValType::i32()]
} else if gen_valid_is_ssa_nomerge_family_config(ctx.config) {
[]
} else {
gen_param_types(ctx)
}
let results = if gen_valid_is_ssa_nomerge_family_config(ctx.config) {
[]
} else if i == 0 && (has_start || total_tag_count > 0) {
[]
} else if ctx.config.features.allow_heap_store_optimization_body_generator &&
i == 1 {
[ValType::i32()]
} else if ctx.config.features.allow_typed_body_generator && i == 1 {
if ctx.config.features.allow_v128 {
[ValType::i32(), ValType::i64(), ValType::v128()]
} else {
[ValType::i32(), ValType::i64()]
}
} else if ctx.config.features.allow_typed_body_generator &&
ctx.config.features.allow_v128 &&
i == 2 {
[ValType::v128()]
} else if gen_valid_is_control_heavy_config(ctx.config) && i == 3 {
[ValType::i32(), ValType::i64()]
} else if exact_result_slot == Some(i) {
[
gc_type_plan.exact_ref_types[ctx.random_int_from(
TypeStream,
gc_type_plan.exact_ref_types.length(),
)],
]
} else {
gen_result_types(ctx, extra_ref_types=gc_type_plan.exact_ref_types)
}
type_params.push(params)
type_results.push(results)
type_defs.push(
RecType::new(SubType::comp_type(CompType::func(params, results))),
)
}
for rec_type in gc_type_defs {
type_defs.push(rec_type)
}
match payload_tag_type_idx {
Some(_) => {
type_defs.push(
RecType::new(SubType::comp_type(CompType::func([ValType::i32()], []))),
)
type_params.push([ValType::i32()])
type_results.push([])
}
None => ()
}
let use_imported_start = has_start &&
import_func_count > 0 &&
config.section_bias.imports_percent == 100 &&
config.section_bias.start_percent == 100 &&
config.max_tables == 0 &&
config.max_mems == 0 &&
config.max_globals == 0 &&
config.max_tags == 0 &&
config.max_elems == 0 &&
config.max_datas == 0
let start_func_idx = if use_imported_start {
FuncIdx::new(0U)
} else {
FuncIdx::new(import_func_count.reinterpret_as_uint())
}
let imports : Array[Import] = []
for i = 0; i < import_func_count; i = i + 1 {
let type_idx = if use_imported_start && i == 0 {
TypeIdx::new(0U)
} else {
gen_valid_pick_func_type_idx(ctx, func_type_count)
}
imports.push(
Import::new(
gen_valid_import_module_name(ctx, i),
gen_valid_name(ctx, "imported_func_\{i}"),
ExternType::func(type_idx),
),
)
}
let imported_tables : Array[TableType] = []
for i = 0; i < import_table_count; i = i + 1 {
let table_type = gen_valid_table_type(ctx, i, gc_type_plan)
imported_tables.push(table_type)
imports.push(
Import::new(
gen_valid_import_module_name(ctx, import_func_count + i),
gen_valid_name(ctx, "imported_table_\{i}"),
ExternType::table(table_type),
),
)
}
let imported_mems : Array[MemType] = []
for i = 0; i < import_mem_count; i = i + 1 {
let mem_type = gen_valid_mem_type(ctx, i)
imported_mems.push(mem_type)
imports.push(
Import::new(
gen_valid_import_module_name(
ctx,
import_func_count + import_table_count + i,
),
gen_valid_name(ctx, "imported_memory_\{i}"),
ExternType::mem(mem_type),
),
)
}
let imported_global_types : Array[GlobalType] = []
for i = 0; i < import_global_count; i = i + 1 {
let global_vt = if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 0 {
ValType::i32()
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 1 {
ValType::externref()
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 2 {
ValType::i64()
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 3 {
match gc_type_plan.descriptor_type_idx {
Some(descriptor_idx) =>
ValType::ref_type(
RefType::new(true, HeapType::new(descriptor_idx), exact=true),
)
None => ValType::externref()
}
} else if i == 0 &&
!gc_type_plan.exact_ref_types.is_empty() &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(GlobalStream, 3) == 0
) {
gc_type_plan.exact_ref_types[ctx.random_int_from(
GlobalStream,
gc_type_plan.exact_ref_types.length(),
)]
} else if i == 0 &&
!gc_type_plan.concrete_ref_types.is_empty() &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(GlobalStream, 3) == 0
) {
gc_type_plan.concrete_ref_types[0]
} else {
let global_ref_types = gc_type_plan.concrete_ref_types.copy()
for vt in gc_type_plan.exact_ref_types {
global_ref_types.push(vt)
}
gen_valid_valtype_with_extra_refs_from(
ctx,
GlobalStream,
global_ref_types,
)
}
let is_mut = if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i <= 3 {
false
} else {
ctx.config.mode == CoverageForced || ctx.random_bool_from(GlobalStream)
}
let global_type = GlobalType::new(global_vt, is_mut)
imported_global_types.push(global_type)
imports.push(
Import::new(
gen_valid_import_module_name(
ctx,
import_func_count + import_table_count + import_mem_count + i,
),
gen_valid_name(ctx, "imported_global_\{i}"),
ExternType::global(global_type),
),
)
}
let imported_tag_types : Array[TagType] = []
for i = 0; i < import_tag_count; i = i + 1 {
let tag_type = TagType::new(
match payload_tag_type_idx {
Some(payload_idx) if i == 1 => payload_idx
_ => TypeIdx::new(0U)
},
)
imported_tag_types.push(tag_type)
imports.push(
Import::new(
gen_valid_import_module_name(
ctx,
import_func_count +
import_table_count +
import_mem_count +
import_global_count +
i,
),
gen_valid_name(ctx, "imported_tag_\{i}"),
ExternType::tag(tag_type),
),
)
}
let first_defined_func_idx = FuncIdx::new(
import_func_count.reinterpret_as_uint(),
)
let globals : Array[Global] = []
let global_types_for_inits = imported_global_types.copy()
for i = 0; i < defined_global_count; i = i + 1 {
let vt = if ctx.config.features.allow_heap_store_optimization_body_generator &&
ctx.config.mode == CoverageForced &&
i == 1 {
match gc_type_plan.descriptor_type_idx {
Some(descriptor_idx) =>
ValType::ref_type(
RefType::new(true, HeapType::new(descriptor_idx), exact=true),
)
None => ValType::i32()
}
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i <= 1 {
ValType::i32()
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 2 {
ValType::funcref()
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 3 &&
!gc_type_plan.struct_type_idxs.is_empty() {
ValType::ref_type(
RefType::new(
true,
HeapType::new(gc_type_plan.struct_type_idxs[0]),
exact=true,
),
)
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 4 {
ValType::ref_type(RefType::new(true, HeapType::new(TypeIdx::new(0U))))
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 5 {
match gc_type_plan.descriptor_struct_idx {
Some(described_idx) =>
ValType::ref_type(
RefType::new(false, HeapType::new(described_idx), exact=true),
)
None => ValType::externref()
}
} else if i == 0 &&
!gc_type_plan.exact_ref_types.is_empty() &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(GlobalStream, 3) == 0
) {
gc_type_plan.exact_ref_types[ctx.random_int_from(
GlobalStream,
gc_type_plan.exact_ref_types.length(),
)]
} else if i == 0 &&
!gc_type_plan.concrete_ref_types.is_empty() &&
(
ctx.config.mode == CoverageForced ||
ctx.random_int_from(GlobalStream, 3) == 0
) {
gc_type_plan.concrete_ref_types[0]
} else {
let global_ref_types = gc_type_plan.concrete_ref_types.copy()
for exact_vt in gc_type_plan.exact_ref_types {
global_ref_types.push(exact_vt)
}
gen_valid_valtype_with_extra_refs_from(
ctx,
GlobalStream,
global_ref_types,
)
}
let is_mut = if ctx.config.features.allow_heap_store_optimization_body_generator &&
ctx.config.mode == CoverageForced &&
i == 1 &&
gc_type_plan.descriptor_type_idx is Some(_) {
true
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i <= 1 {
false
} else {
ctx.config.mode == CoverageForced || ctx.random_bool_from(GlobalStream)
}
let global_type = GlobalType::new(vt, is_mut)
let init_expr = if ctx.config.features.allow_heap_store_optimization_body_generator &&
ctx.config.mode == CoverageForced &&
i == 1 {
match gc_type_plan.descriptor_type_idx {
Some(descriptor_idx) =>
Expr::new([Instruction::struct_new_default(descriptor_idx)])
None =>
gen_valid_const_expr_for_global(
ctx, vt, global_types_for_inits, first_defined_func_idx, gc_type_plan,
)
}
} else if ctx.config.features.allow_const_expr_variants &&
ctx.config.mode == CoverageForced &&
i == 0 &&
vt == ValType::i32() {
Expr::new([Instruction::i32_const(0)])
} else {
gen_valid_const_expr_for_global(
ctx, vt, global_types_for_inits, first_defined_func_idx, gc_type_plan,
)
}
globals.push(Global::new(global_type, init_expr))
global_types_for_inits.push(global_type)
}
let global_types = global_types_for_inits
let func_type_idxs : Array[TypeIdx] = []
for i = 0; i < defined_func_count; i = i + 1 {
func_type_idxs.push(
if i == 0 && (has_start || ctx.config.mode == CoverageForced) {
TypeIdx::new(0U)
} else if has_start &&
ctx.config.mode == CoverageForced &&
config.section_bias.start_percent == 100 &&
config.max_tables == 0 &&
config.max_mems == 0 &&
config.max_globals == 0 &&
config.max_tags == 0 &&
config.max_elems == 0 &&
config.max_datas == 0 &&
i == 1 {
TypeIdx::new(0U)
} else if ctx.config.features.allow_heap_store_optimization_body_generator &&
i == 1 &&
func_type_count > 1 {
TypeIdx::new(1U)
} else if ctx.config.features.allow_typed_body_generator &&
i == 1 &&
func_type_count > 1 {
TypeIdx::new(1U)
} else if gen_valid_is_control_heavy_config(config) &&
i == 2 &&
func_type_count > 3 {
TypeIdx::new(3U)
} else if gen_valid_is_control_heavy_config(config) &&
i == defined_func_count - 1 &&
func_type_count > 1 {
TypeIdx::new(1U)
} else {
gen_valid_pick_func_type_idx(ctx, func_type_count)
},
)
}
let tables : Array[Table] = []
for i = 0; i < defined_table_count; i = i + 1 {
let total_table_idx = import_table_count + i
let table_type = gen_valid_table_type(ctx, total_table_idx, gc_type_plan)
let TableType(table_ref_type, _) = table_type
tables.push(
Table::new(
table_type,
gen_valid_table_init_expr(
ctx, total_table_idx, table_ref_type, first_defined_func_idx, imported_global_types,
gc_type_plan,
),
),
)
}
let table_types = imported_tables.copy()
for table in tables {
let Table(table_type, _) = table
table_types.push(table_type)
}
let mems : Array[MemType] = imported_mems.copy()
let defined_mems : Array[MemType] = []
for i = 0; i < defined_mem_count; i = i + 1 {
let mem_type = gen_valid_mem_type(ctx, import_mem_count + i)
defined_mems.push(mem_type)
mems.push(mem_type)
}
let func_sigs : Array[GenValidFuncSig] = []
for i = 0; i < imports.length(); i = i + 1 {
let Import(_, _, extern_type) = imports[i]
match extern_type {
FuncExternType(type_idx) => {
let type_idx_i = match type_idx {
TypeIdx(type_idx_u) => type_idx_u.reinterpret_as_int()
RecIdx(type_idx_u) => type_idx_u.reinterpret_as_int()
}
func_sigs.push({
idx: FuncIdx::new(i.reinterpret_as_uint()),
type_idx,
params: type_params[type_idx_i],
results: type_results[type_idx_i],
})
}
_ => ()
}
}
for i = 0; i < func_type_idxs.length(); i = i + 1 {
let type_idx = func_type_idxs[i]
let type_idx_i = match type_idx {
TypeIdx(type_idx_u) => type_idx_u.reinterpret_as_int()
RecIdx(type_idx_u) => type_idx_u.reinterpret_as_int()
}
func_sigs.push({
idx: FuncIdx::new((import_func_count + i).reinterpret_as_uint()),
type_idx,
params: type_params[type_idx_i],
results: type_results[type_idx_i],
})
}
let total_func_count = import_func_count + defined_func_count
let imported_i32_global_idx = if ctx.config.features.allow_const_expr_variants {
gen_matching_immutable_global_idx(imported_global_types, ValType::i32())
} else {
None
}
let imported_i64_global_idx = if ctx.config.features.allow_const_expr_variants {
gen_matching_immutable_global_idx(imported_global_types, ValType::i64())
} else {
None
}
let const_i32_global_idx = match imported_i32_global_idx {
Some(idx) => Some(idx)
None =>
if ctx.config.features.allow_const_expr_variants {
gen_matching_immutable_global_idx(global_types, ValType::i32())
} else {
None
}
}
let tags : Array[TagType] = []
for i = 0; i < defined_tag_count; i = i + 1 {
tags.push(
TagType::new(
match payload_tag_type_idx {
Some(payload_idx) if i == 1 => payload_idx
_ => TypeIdx::new(0U)
},
),
)
}
let all_tags = imported_tag_types.copy()
for tag in tags {
all_tags.push(tag)
}
let elems : Array[Elem] = []
if total_table_count > 0 && total_func_count > 0 {
for i = 0; i < elem_count; i = i + 1 {
let func_idx = gen_valid_pick_func_idx(
ctx, total_func_count, first_defined_func_idx,
)
let FuncIdx(func_idx_u) = func_idx
let second_func_idx_u = ((func_idx_u.reinterpret_as_int() + 1) %
total_func_count).reinterpret_as_uint()
let second_func_idx = FuncIdx::new(second_func_idx_u)
let gc_table_choice = if table_types.length() > 1 {
Some(
TableIdx::new(
(1 + ctx.random_int_from(ElemStream, table_types.length() - 1)).reinterpret_as_uint(),
),
)
} else {
None
}
let gc_table_ref_type = match gc_table_choice {
Some(table_idx) => {
let TableIdx(table_idx_u) = table_idx
let TableType(rt, _) = table_types[table_idx_u.reinterpret_as_int()]
Some(rt)
}
None => None
}
let elem = if ctx.config.mode == CoverageForced && i == 0 {
Elem::new(
ElemMode::active(
TableIdx::new(0U),
gen_valid_active_i32_offset_from(
ctx,
ElemStream,
global_idx=imported_i32_global_idx,
),
),
ElemKind::funcs([func_idx, second_func_idx]),
)
} else if ctx.config.mode == CoverageForced && i == 1 {
Elem::new(
ElemMode::passive(),
ElemKind::typed_exprs(RefType::abs(AbsHeapType::func()), [
gen_valid_funcref_expr(ctx, func_idx),
]),
)
} else if ctx.config.mode == CoverageForced && i == 2 {
Elem::new(
ElemMode::declarative(),
ElemKind::func_exprs([gen_valid_funcref_expr(ctx, func_idx)]),
)
} else if ctx.config.mode == CoverageForced && i == 3 {
match gen_valid_first_nonzero_funcref_table_idx(table_types) {
Some(table_idx) =>
Elem::new(
ElemMode::active(
table_idx,
gen_valid_active_i32_boundary_offset(),
),
ElemKind::funcs([func_idx, second_func_idx]),
)
None =>
match (gc_table_choice, gc_table_ref_type) {
(Some(table_idx), Some(rt)) if ValType::ref_type(rt) !=
ValType::funcref() =>
Elem::new(
ElemMode::active(
table_idx,
gen_valid_active_i32_boundary_offset(),
),
ElemKind::typed_exprs(rt, [
gen_valid_elem_ref_expr(ctx, rt, gc_type_plan~),
]),
)
_ =>
match gc_type_plan.bulk_elem_ref_type {
Some(rt) =>
Elem::new(
ElemMode::passive(),
ElemKind::typed_exprs(rt, [
gen_valid_elem_ref_expr(ctx, rt, gc_type_plan~),
gen_valid_elem_ref_expr(ctx, rt, gc_type_plan~),
]),
)
None =>
Elem::new(ElemMode::passive(), ElemKind::funcs([func_idx]))
}
}
}
} else if ctx.config.mode == CoverageForced && i == 4 {
match gen_valid_first_array_const_expr_shape(gc_type_plan) {
Some(shape) =>
Elem::new(
ElemMode::passive(),
ElemKind::typed_exprs(
gen_valid_array_ref_type_from_shape(shape),
[
gen_valid_array_const_expr_from_shape(
ctx,
ElemStream,
shape,
ArrayNewDefaultConstExpr,
),
],
),
)
None => Elem::new(ElemMode::passive(), ElemKind::funcs([func_idx]))
}
} else if ctx.config.mode == CoverageForced && i == 5 {
match gen_valid_first_array_const_expr_shape(gc_type_plan) {
Some(shape) =>
Elem::new(
ElemMode::passive(),
ElemKind::typed_exprs(
gen_valid_array_ref_type_from_shape(shape),
[
gen_valid_array_const_expr_from_shape(
ctx,
ElemStream,
shape,
ArrayNewConstExpr,
),
],
),
)
None => Elem::new(ElemMode::passive(), ElemKind::funcs([func_idx]))
}
} else if (match gc_type_plan.bulk_elem_ref_type {
Some(_) => ctx.random_int_from(ElemStream, 4) == 0
None => false
}) {
match gc_type_plan.bulk_elem_ref_type {
Some(rt) =>
Elem::new(
ElemMode::passive(),
ElemKind::typed_exprs(rt, [
gen_valid_elem_ref_expr(ctx, rt, gc_type_plan~),
]),
)
None => Elem::new(ElemMode::passive(), ElemKind::funcs([func_idx]))
}
} else if (match gc_table_ref_type {
Some(rt) =>
ValType::ref_type(rt) != ValType::funcref() &&
ctx.random_int_from(ElemStream, 3) == 0
None => false
}) {
match (gc_table_choice, gc_table_ref_type) {
(Some(table_idx), Some(rt)) =>
Elem::new(
ElemMode::active(
table_idx,
gen_valid_active_i32_offset_from(
ctx,
ElemStream,
global_idx=const_i32_global_idx,
),
),
ElemKind::typed_exprs(rt, [
gen_valid_elem_ref_expr(ctx, rt, gc_type_plan~),
]),
)
_ => Elem::new(ElemMode::passive(), ElemKind::funcs([func_idx]))
}
} else {
match ctx.random_int_from(ElemStream, 7) {
0 =>
Elem::new(
ElemMode::active(
TableIdx::new(0U),
gen_valid_active_i32_offset_from(
ctx,
ElemStream,
global_idx=const_i32_global_idx,
),
),
ElemKind::funcs([func_idx]),
)
1 => Elem::new(ElemMode::passive(), ElemKind::funcs([func_idx]))
2 => Elem::new(ElemMode::declarative(), ElemKind::funcs([func_idx]))
3 =>
Elem::new(
ElemMode::passive(),
ElemKind::typed_exprs(RefType::abs(AbsHeapType::func()), [
gen_valid_funcref_expr(ctx, func_idx),
]),
)
4 =>
Elem::new(
ElemMode::active(
TableIdx::new(0U),
gen_valid_active_i32_offset_from(
ctx,
ElemStream,
global_idx=const_i32_global_idx,
),
),
ElemKind::func_exprs([gen_valid_funcref_expr(ctx, func_idx)]),
)
5 =>
match (gc_table_choice, gc_table_ref_type) {
(Some(table_idx), Some(rt)) if ValType::ref_type(rt) !=
ValType::funcref() =>
Elem::new(
ElemMode::active(
table_idx,
gen_valid_active_i32_offset(
ctx,
global_idx=const_i32_global_idx,
),
),
ElemKind::typed_exprs(rt, [
gen_valid_elem_ref_expr(ctx, rt, gc_type_plan~),
]),
)
_ => Elem::new(ElemMode::passive(), ElemKind::funcs([func_idx]))
}
_ =>
match gc_table_ref_type {
Some(rt) if ValType::ref_type(rt) != ValType::funcref() =>
Elem::new(
ElemMode::passive(),
ElemKind::typed_exprs(rt, [
gen_valid_elem_ref_expr(ctx, rt, gc_type_plan~),
]),
)
_ =>
Elem::new(
ElemMode::declarative(),
ElemKind::func_exprs([gen_valid_funcref_expr(ctx, func_idx)]),
)
}
}
}
elems.push(elem)
}
}
let elem_idxs : Array[ElemIdx] = []
let passive_elem_idxs : Array[ElemIdx] = []
let passive_elem_ref_types : Array[RefType] = []
let mut bulk_elem_seed_idx : ElemIdx? = None
for i = 0; i < elems.length(); i = i + 1 {
let elem_idx = ElemIdx::new(i.reinterpret_as_uint())
let Elem(mode, kind) = elems[i]
match mode {
Active(_, _) => ()
Passive => {
elem_idxs.push(elem_idx)
passive_elem_idxs.push(elem_idx)
passive_elem_ref_types.push(elems[i].reftype())
match (bulk_elem_seed_idx, gc_type_plan.bulk_elem_ref_type, kind) {
(None, Some(seed_rt), TypedExprsElemKind(rt, _)) if rt == seed_rt =>
bulk_elem_seed_idx = Some(elem_idx)
_ => ()
}
}
Declarative => elem_idxs.push(elem_idx)
}
}
let datas : Array[Data] = []
if total_mem_count > 0 {
for i = 0; i < data_count; i = i + 1 {
let data = if ctx.config.mode == CoverageForced && i == 0 {
Data::new(
DataMode::active(
if total_mem_count > 1 {
MemIdx::new(1U)
} else {
MemIdx::new(0U)
},
gen_valid_active_i32_offset_from(
ctx,
DataStream,
global_idx=imported_i32_global_idx,
),
),
gen_valid_payload(ctx, b"gen-valid-active-with-a-larger-payload"),
)
} else if ctx.config.mode == CoverageForced && i == 1 {
Data::new(DataMode::passive(), gen_valid_payload(ctx, b""))
} else if ctx.config.mode == CoverageForced && i == 2 {
let memory64_data_target = if ctx.config.max_mems > 2 {
gen_valid_first_memory64_mem_idx(mems)
} else {
None
}
match memory64_data_target {
Some(mem_idx) => {
let MemIdx(mem_idx_u) = mem_idx
let mem_type = mems[mem_idx_u.reinterpret_as_int()]
Data::new(
DataMode::active(
mem_idx,
match imported_i64_global_idx {
Some(_) =>
gen_valid_active_offset_from(
ctx,
DataStream,
gen_valid_mem_type_addr_type(mem_type),
global_idx=imported_i64_global_idx,
)
None => gen_valid_active_i64_boundary_offset()
},
),
gen_valid_payload(ctx, b""),
)
}
None =>
Data::new(
DataMode::active(
MemIdx::new(0U),
Expr::new([Instruction::i32_const(0)]),
),
gen_valid_payload(ctx, b""),
)
}
} else if ctx.config.mode == CoverageForced && i == 3 {
Data::new(
DataMode::active(
MemIdx::new(0U),
gen_valid_active_i32_boundary_offset(),
),
gen_valid_payload(ctx, b""),
)
} else {
let payload = match ctx.random_int_from(DataStream, 4) {
0 => b""
1 => b"gen-valid"
2 => b"bulk-seed"
_ => b"\x00\x01\x02"
}
if ctx.random_int_from(DataStream, 3) == 0 {
Data::new(DataMode::passive(), gen_valid_payload(ctx, payload))
} else {
let mem_idx = if total_mem_count > 1 &&
ctx.random_int_from(DataStream, 4) == 0 {
MemIdx::new(1U)
} else {
MemIdx::new(0U)
}
let offset = if ctx.random_int_from(DataStream, 3) == 0 {
Expr::new([
Instruction::i32_const(ctx.random_int_from(DataStream, 4)),
])
} else {
gen_valid_active_i32_offset_from(
ctx,
DataStream,
global_idx=const_i32_global_idx,
)
}
Data::new(
DataMode::active(mem_idx, offset),
gen_valid_payload(ctx, payload),
)
}
}
datas.push(data)
}
}
let data_idxs : Array[DataIdx] = []
for i = 0; i < datas.length(); i = i + 1 {
let Data(mode, _) = datas[i]
match mode {
Active(_, _) => ()
Passive => data_idxs.push(DataIdx::new(i.reinterpret_as_uint()))
}
}
let funcs : Array[Func] = []
for i = 0; i < func_type_idxs.length(); i = i + 1 {
let type_idx = func_type_idxs[i]
let type_idx_i = match type_idx {
TypeIdx(type_idx_u) => type_idx_u.reinterpret_as_int()
RecIdx(type_idx_u) => type_idx_u.reinterpret_as_int()
}
if has_start &&
ctx.config.mode == CoverageForced &&
config.section_bias.start_percent == 100 &&
config.max_tables == 0 &&
config.max_mems == 0 &&
config.max_globals == 0 &&
config.max_tags == 0 &&
config.max_elems == 0 &&
config.max_datas == 0 &&
i == 0 &&
func_type_idxs.length() > 1 &&
type_params[type_idx_i].is_empty() &&
type_results[type_idx_i].is_empty() {
funcs.push(
Func::new(
Locals::empty(),
Expr::new([
Instruction::call(
FuncIdx::new((import_func_count + 1).reinterpret_as_uint()),
),
]),
),
)
} else if gen_valid_is_control_heavy_config(config) &&
i == 0 &&
type_params[type_idx_i].is_empty() &&
type_results[type_idx_i].is_empty() {
funcs.push(Func::new(Locals::empty(), Expr::new([])))
} else if config.features.allow_heap_store_optimization_body_generator &&
i == 1 &&
type_params[type_idx_i].is_empty() &&
type_results[type_idx_i] == [ValType::i32()] {
funcs.push(
Func::new(
Locals::empty(),
Expr::new([Instruction::i32_const(I32(139))]),
),
)
} else if gen_valid_is_control_heavy_config(config) &&
i == func_type_idxs.length() - 1 &&
type_results[type_idx_i].length() > 1 {
funcs.push(
Func::new(Locals::empty(), Expr::new([Instruction::unreachable_()])),
)
} else {
funcs.push(
gen_valid_build_func(
ctx,
type_params[type_idx_i],
type_results[type_idx_i],
global_types,
table_types,
mems,
all_tags,
func_sigs,
data_idxs,
elem_idxs,
passive_elem_idxs,
passive_elem_ref_types,
bulk_elem_seed_idx,
gc_type_plan,
Some(first_defined_func_idx),
current_func_idx=Some(
FuncIdx::new((import_func_count + i).reinterpret_as_uint()),
),
),
)
}
}
let topology_export_mode = if gen_valid_is_topology_heavy_config(config) {
ctx.random_int_from(ModuleTopologyStream, 8)
} else {
7
}
let exports : Array[Export] = []
if topology_export_mode != 0 {
let primary_func_export_name = if topology_export_mode == 1 {
"entry"
} else {
"main"
}
let alias_func_export_name = if topology_export_mode == 1 {
"entry.alias"
} else {
"main.alias"
}
exports.push(
Export::new(
gen_valid_name(ctx, primary_func_export_name),
ExternIdx::func(first_defined_func_idx),
),
)
if gen_valid_is_topology_heavy_config(config) {
exports.push(
Export::new(
gen_valid_name(ctx, alias_func_export_name),
ExternIdx::func(first_defined_func_idx),
),
)
exports.push(
Export::new(
gen_valid_name(ctx, "entrypoint.alias.0"),
ExternIdx::func(first_defined_func_idx),
),
)
exports.push(
Export::new(
gen_valid_name(ctx, "entrypoint.alias.1"),
ExternIdx::func(first_defined_func_idx),
),
)
if import_func_count > 0 {
exports.push(
Export::new(
gen_valid_name(ctx, "imported_func_0.reexport"),
ExternIdx::func(FuncIdx::new(0U)),
),
)
}
}
if total_table_count > 0 {
exports.push(
Export::new(
gen_valid_name(ctx, "table0"),
ExternIdx::table(TableIdx::new(0U)),
),
)
if gen_valid_is_topology_heavy_config(config) {
exports.push(
Export::new(
gen_valid_name(ctx, "table0.alias"),
ExternIdx::table(TableIdx::new(0U)),
),
)
}
if gen_valid_is_topology_heavy_config(config) && total_table_count > 1 {
exports.push(
Export::new(
gen_valid_name(ctx, "table1"),
ExternIdx::table(TableIdx::new(1U)),
),
)
}
}
if total_mem_count > 0 {
exports.push(
Export::new(
gen_valid_name(ctx, "memory0"),
ExternIdx::mem(MemIdx::new(0U)),
),
)
if gen_valid_is_topology_heavy_config(config) {
exports.push(
Export::new(
gen_valid_name(ctx, "memory0.alias"),
ExternIdx::mem(MemIdx::new(0U)),
),
)
}
if gen_valid_is_topology_heavy_config(config) && total_mem_count > 1 {
exports.push(
Export::new(
gen_valid_name(ctx, "memory1"),
ExternIdx::mem(MemIdx::new(1U)),
),
)
}
}
if total_global_count > 0 {
exports.push(
Export::new(
gen_valid_name(ctx, "global0"),
ExternIdx::global(GlobalIdx::new(0U)),
),
)
if gen_valid_is_topology_heavy_config(config) {
exports.push(
Export::new(
gen_valid_name(ctx, "global0.alias"),
ExternIdx::global(GlobalIdx::new(0U)),
),
)
}
if gen_valid_is_topology_heavy_config(config) && total_global_count > 1 {
exports.push(
Export::new(
gen_valid_name(ctx, "global1"),
ExternIdx::global(GlobalIdx::new(1U)),
),
)
}
}
if total_tag_count > 0 {
exports.push(
Export::new(
gen_valid_name(ctx, "tag0"),
ExternIdx::tag(TagIdx::new(0U)),
),
)
if gen_valid_is_topology_heavy_config(config) {
exports.push(
Export::new(
gen_valid_name(ctx, "tag0.alias"),
ExternIdx::tag(TagIdx::new(0U)),
),
)
}
if gen_valid_is_topology_heavy_config(config) && total_tag_count > 1 {
exports.push(
Export::new(
gen_valid_name(ctx, "tag1"),
ExternIdx::tag(TagIdx::new(1U)),
),
)
}
}
}
let mut mod = Module::new().with_type_sec(TypeSec::new(type_defs))
if !imports.is_empty() {
mod = mod.with_import_sec(ImportSec::new(imports))
}
mod = mod.with_func_sec(FuncSec::new(func_type_idxs))
if !tables.is_empty() {
mod = mod.with_table_sec(TableSec::new(tables))
}
if !defined_mems.is_empty() {
mod = mod.with_mem_sec(MemSec::new(defined_mems))
}
if !globals.is_empty() {
mod = mod.with_global_sec(GlobalSec::new(globals))
}
if !tags.is_empty() {
mod = mod.with_tag_sec(TagSec::new(tags))
}
if has_start {
mod = mod.with_start_sec(StartSec::new(start_func_idx))
}
if !elems.is_empty() {
mod = mod.with_elem_sec(ElemSec::new(elems))
}
if !datas.is_empty() {
mod = mod.with_data_cnt_sec(
DataCntSec::new(U32(datas.length().reinterpret_as_uint())),
)
}
mod = mod.with_code_sec(CodeSec::new(funcs))
if !datas.is_empty() {
mod = mod.with_data_sec(DataSec::new(datas))
}
if config.features.allow_name_custom_sections &&
(
config.mode == CoverageForced ||
ctx.random_int_from(ModuleTopologyStream, 3) == 0
) {
let func_name_entries : Array[NameAssoc] = []
if !funcs.is_empty() {
func_name_entries.push(
NameAssoc::new(0U, gen_valid_name(ctx, "fzg_func0")),
)
}
let type_name_entries : Array[NameAssoc] = []
if !type_defs.is_empty() {
type_name_entries.push(
NameAssoc::new(0U, gen_valid_name(ctx, "fzg_type0")),
)
}
let table_name_entries : Array[NameAssoc] = []
if total_table_count > 0 {
table_name_entries.push(
NameAssoc::new(0U, gen_valid_name(ctx, "fzg_table0")),
)
}
let memory_name_entries : Array[NameAssoc] = []
if total_mem_count > 0 {
memory_name_entries.push(
NameAssoc::new(0U, gen_valid_name(ctx, "fzg_memory0")),
)
}
let global_name_entries : Array[NameAssoc] = []
if total_global_count > 0 {
global_name_entries.push(
NameAssoc::new(0U, gen_valid_name(ctx, "fzg_global0")),
)
}
let elem_name_entries : Array[NameAssoc] = []
if !elems.is_empty() {
elem_name_entries.push(
NameAssoc::new(0U, gen_valid_name(ctx, "fzg_elem0")),
)
}
let data_name_entries : Array[NameAssoc] = []
if !datas.is_empty() {
data_name_entries.push(
NameAssoc::new(0U, gen_valid_name(ctx, "fzg_data0")),
)
}
let tag_name_entries : Array[NameAssoc] = []
if total_tag_count > 0 {
tag_name_entries.push(NameAssoc::new(0U, gen_valid_name(ctx, "fzg_tag0")))
}
let local_name_entries : Array[IndirectNameAssoc] = []
if gen_valid_is_control_heavy_config(config) && funcs.length() > 2 {
let first_local_names = NameMap::new([
NameAssoc::new(0U, gen_valid_name(ctx, "fzg_param0")),
NameAssoc::new(1U, gen_valid_name(ctx, "fzg_param1")),
])
local_name_entries.push(IndirectNameAssoc::new(2U, first_local_names))
} else if gen_valid_is_topology_heavy_config(config) {
for i = 0; i < func_type_idxs.length(); i = i + 1 {
let type_idx = func_type_idxs[i]
let type_idx_i = match type_idx {
TypeIdx(type_idx_u) => type_idx_u.reinterpret_as_int()
RecIdx(type_idx_u) => type_idx_u.reinterpret_as_int()
}
let Func(locals, _) = funcs[i]
let local_count = type_params[type_idx_i].length() + locals.length()
let local_names : Array[NameAssoc] = []
for local_idx = 0; local_idx < local_count; local_idx = local_idx + 1 {
local_names.push(
NameAssoc::new(
local_idx.reinterpret_as_uint(),
gen_valid_name(ctx, "fzg_local\{i}_\{local_idx}"),
),
)
}
if !local_names.is_empty() {
local_name_entries.push(
IndirectNameAssoc::new(
(import_func_count + i).reinterpret_as_uint(),
NameMap::new(local_names),
),
)
}
}
}
let label_name_entries : Array[IndirectNameAssoc] = []
if gen_valid_is_topology_heavy_config(config) {
for i = 0; i < funcs.length(); i = i + 1 {
let Func(_, body) = funcs[i]
let label_count = gen_valid_label_count_expr(body)
let label_names : Array[NameAssoc] = []
for label_idx = 0; label_idx < label_count; label_idx = label_idx + 1 {
label_names.push(
NameAssoc::new(
label_idx.reinterpret_as_uint(),
gen_valid_name(ctx, "fzg_label\{i}_\{label_idx}"),
),
)
}
if !label_names.is_empty() {
label_name_entries.push(
IndirectNameAssoc::new(
(import_func_count + i).reinterpret_as_uint(),
NameMap::new(label_names),
),
)
}
}
}
let name_sec = NameSec::new(
module_name=Some(gen_valid_name(ctx, "fzg_module")),
func_names=if func_name_entries.is_empty() {
None
} else {
Some(NameMap::new(func_name_entries))
},
type_names=if type_name_entries.is_empty() {
None
} else {
Some(NameMap::new(type_name_entries))
},
table_names=if table_name_entries.is_empty() {
None
} else {
Some(NameMap::new(table_name_entries))
},
memory_names=if memory_name_entries.is_empty() {
None
} else {
Some(NameMap::new(memory_name_entries))
},
global_names=if global_name_entries.is_empty() {
None
} else {
Some(NameMap::new(global_name_entries))
},
elem_names=if elem_name_entries.is_empty() {
None
} else {
Some(NameMap::new(elem_name_entries))
},
data_names=if data_name_entries.is_empty() {
None
} else {
Some(NameMap::new(data_name_entries))
},
tag_names=if tag_name_entries.is_empty() {
None
} else {
Some(NameMap::new(tag_name_entries))
},
local_names=if local_name_entries.is_empty() {
None
} else {
Some(IndirectNameMap::new(local_name_entries))
},
label_names=if label_name_entries.is_empty() {
None
} else {
Some(IndirectNameMap::new(label_name_entries))
},
)
mod = mod.with_name_sec(name_sec)
let custom_secs = if gen_valid_is_topology_heavy_config(config) {
[
@lib.CustomSec::new(
gen_valid_name(ctx, "fzg.custom.leading.empty"),
gen_valid_payload(ctx, b""),
),
@lib.CustomSec::new(
gen_valid_name(ctx, "fzg.custom.before-type.high-bytes"),
gen_valid_payload(ctx, b"\xff\x00\x80\x7f\xfe\xfd\xfc\x00"),
),
@lib.CustomSec::new(
gen_valid_name(ctx, "fzg.custom.unicode-name"),
gen_valid_payload(ctx, b"utf8-name custom payload"),
),
@lib.CustomSec::new(
gen_valid_name(ctx, "fzg.custom.long-payload"),
gen_valid_payload(
ctx, b"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
),
),
@lib.CustomSec::new(
gen_valid_name(ctx, "fzg.custom.name-like"),
gen_valid_payload(ctx, b"name\x00\x01payload-but-not-name-section"),
),
@lib.CustomSec::new(
gen_valid_name(ctx, "fzg.custom.arbitrary-bytes"),
gen_valid_payload(
ctx, b"\x00\xff\x01\xfe\x02\xfd\x03\xfc\x04\xfb\x05\xfa\x06\xf9\x07\xf8",
),
),
]
} else {
[
@lib.CustomSec::new(
gen_valid_name(ctx, "fzg.custom"),
gen_valid_payload(ctx, b"valid-fzg-custom"),
),
]
}
mod = mod.with_custom_secs(custom_secs)
}
if exports.is_empty() {
mod
} else {
mod.with_export_sec(ExportSec::new(exports))
}
}
///|
fn gen_valid_module_once_with_config(
rnd : RandomState,
config : GenValidConfig,
) -> Module {
gen_valid_module_once_with_context(GenValidContext::new(rnd, config))
}
///|
fn gen_valid_module_once_with_stream_seed(
seed : UInt64,
config : GenValidConfig,
) -> Module {
gen_valid_module_once_with_context(
GenValidContext::new_streamed(seed, config),
)
}
///|
fn gen_valid_instruction_count_expr(expr : Expr) -> Int32 {
let Expr(instrs) = expr
gen_valid_instruction_count_instrs(instrs)
}
///|
fn gen_valid_instruction_count_instrs(instrs : Array[Instruction]) -> Int32 {
let mut total = 0
for instr in instrs {
total += gen_valid_instruction_count_instr(instr)
}
total
}
///|
fn gen_valid_instruction_count_instr(instr : Instruction) -> Int32 {
match instr {
Block(_, body) | Loop(_, body) | TryTable(_, _, body) =>
1 + gen_valid_instruction_count_expr(body)
If(_, then_body, else_body) => {
let else_count = match else_body {
Some(instrs) => gen_valid_instruction_count_instrs(instrs)
None => 0
}
1 + gen_valid_instruction_count_instrs(then_body) + else_count
}
_ => 1
}
}
///|
fn gen_valid_label_count_expr(expr : Expr) -> Int32 {
let Expr(instrs) = expr
gen_valid_label_count_instrs(instrs)
}
///|
fn gen_valid_label_count_instrs(instrs : Array[Instruction]) -> Int32 {
let mut total = 0
for instr in instrs {
total += gen_valid_label_count_instr(instr)
}
total
}
///|
fn gen_valid_label_count_instr(instr : Instruction) -> Int32 {
match instr {
Block(_, body) | Loop(_, body) | TryTable(_, _, body) =>
1 + gen_valid_label_count_expr(body)
If(_, then_body, else_body) => {
let else_count = match else_body {
Some(instrs) => gen_valid_label_count_instrs(instrs)
None => 0
}
1 + gen_valid_label_count_instrs(then_body) + else_count
}
_ => 0
}
}
///|
fn gen_valid_module_instruction_count(mod_ : Module) -> Int32 {
match mod_.code_sec {
Some(CodeSec(funcs)) => {
let mut total = 0
for func in funcs {
let Func(_, body) = func
total += gen_valid_instruction_count_expr(body)
}
total
}
None => 0
}
}
///|
fn gen_valid_expr_depth_expr(expr : Expr) -> Int32 {
let Expr(instrs) = expr
gen_valid_expr_depth_instrs(instrs)
}
///|
fn gen_valid_expr_depth_instrs(instrs : Array[Instruction]) -> Int32 {
let mut max_depth = 0
for instr in instrs {
let depth = gen_valid_expr_depth_instr(instr)
if depth > max_depth {
max_depth = depth
}
}
max_depth
}
///|
fn gen_valid_expr_depth_instr(instr : Instruction) -> Int32 {
match instr {
Block(_, body) | Loop(_, body) | TryTable(_, _, body) =>
1 + gen_valid_expr_depth_expr(body)
If(_, then_body, else_body) => {
let else_depth = match else_body {
Some(instrs) => gen_valid_expr_depth_instrs(instrs)
None => 0
}
let then_depth = gen_valid_expr_depth_instrs(then_body)
if then_depth >= else_depth {
1 + then_depth
} else {
1 + else_depth
}
}
_ => 0
}
}
///|
fn gen_valid_module_expression_depth(mod_ : Module) -> Int32 {
match mod_.code_sec {
Some(CodeSec(funcs)) => {
let mut max_depth = 0
for func in funcs {
let Func(_, body) = func
let depth = gen_valid_expr_depth_expr(body)
if depth > max_depth {
max_depth = depth
}
}
max_depth
}
None => 0
}
}
///|
fn gen_valid_module_segment_payload_size(mod_ : Module) -> Int32 {
let mut total = 0
match mod_.data_sec {
Some(DataSec(datas)) =>
for data in datas {
let Data(_, bytes) = data
total += bytes.length()
}
None => ()
}
for custom in mod_.custom_secs {
let @lib.CustomSec(_, bytes) = custom
total += bytes.length()
}
total
}
///|
fn gen_valid_rec_group_size(rec_type : RecType) -> Int32 {
match rec_type {
SingleRecType(_) => 1
GroupRecType(sub_types) => sub_types.length()
}
}
///|
fn gen_valid_module_max_rec_group_size(mod_ : Module) -> Int32 {
match mod_.type_sec {
Some(TypeSec(types)) => {
let mut max_size = 0
for rec_type in types {
let size = gen_valid_rec_group_size(rec_type)
if size > max_size {
max_size = size
}
}
max_size
}
None => 0
}
}
///|
fn gen_valid_module_section_count(mod_ : Module) -> Int32 {
let mut total = mod_.custom_secs.length()
match mod_.type_sec {
Some(_) => total += 1
None => ()
}
match mod_.import_sec {
Some(_) => total += 1
None => ()
}
match mod_.func_annotation_sec {
Some(_) => total += 1
None => ()
}
match mod_.func_sec {
Some(_) => total += 1
None => ()
}
match mod_.table_sec {
Some(_) => total += 1
None => ()
}
match mod_.mem_sec {
Some(_) => total += 1
None => ()
}
match mod_.global_sec {
Some(_) => total += 1
None => ()
}
match mod_.export_sec {
Some(_) => total += 1
None => ()
}
match mod_.start_sec {
Some(_) => total += 1
None => ()
}
match mod_.elem_sec {
Some(_) => total += 1
None => ()
}
match mod_.data_cnt_sec {
Some(_) => total += 1
None => ()
}
match mod_.code_sec {
Some(_) => total += 1
None => ()
}
match mod_.data_sec {
Some(_) => total += 1
None => ()
}
match mod_.name_sec {
Some(_) => total += 1
None => ()
}
match mod_.tag_sec {
Some(_) => total += 1
None => ()
}
total
}
///|
fn gen_valid_module_byte_size_estimate(mod_ : Module) -> Int32 {
let mut total = 8
match mod_.type_sec {
Some(TypeSec(types)) => total += types.length() * 8
None => ()
}
match mod_.import_sec {
Some(ImportSec(imports)) => total += imports.length() * 12
None => ()
}
match mod_.func_sec {
Some(FuncSec(funcs)) => total += funcs.length() * 4
None => ()
}
match mod_.table_sec {
Some(TableSec(tables)) => total += tables.length() * 8
None => ()
}
match mod_.mem_sec {
Some(MemSec(mems)) => total += mems.length() * 8
None => ()
}
match mod_.global_sec {
Some(GlobalSec(globals)) => total += globals.length() * 12
None => ()
}
match mod_.tag_sec {
Some(TagSec(tags)) => total += tags.length() * 6
None => ()
}
match mod_.elem_sec {
Some(ElemSec(elems)) => total += elems.length() * 12
None => ()
}
total += gen_valid_module_instruction_count(mod_)
total += gen_valid_module_segment_payload_size(mod_)
total
}
///|
fn gen_valid_budget_error(
mod_ : Module,
config : GenValidConfig,
) -> (GenValidBudgetStop, String)? {
match config.max_instruction_count_budget {
Some(limit) => {
let actual = gen_valid_module_instruction_count(mod_)
if actual > limit {
return Some(
(
InstructionCountBudgetExceeded,
"gen-valid instruction budget exceeded: actual \{actual}, limit \{limit}",
),
)
}
}
None => ()
}
match config.max_expression_depth_budget {
Some(limit) => {
let actual = gen_valid_module_expression_depth(mod_)
if actual > limit {
return Some(
(
ExpressionDepthBudgetExceeded,
"gen-valid expression depth budget exceeded: actual \{actual}, limit \{limit}",
),
)
}
}
None => ()
}
match config.max_module_byte_size_budget {
Some(limit) => {
let actual = gen_valid_module_byte_size_estimate(mod_)
if actual > limit {
return Some(
(
ModuleByteSizeBudgetExceeded,
"gen-valid byte-size budget exceeded: actual \{actual}, limit \{limit}",
),
)
}
}
None => ()
}
match config.max_rec_group_size_budget {
Some(limit) => {
let actual = gen_valid_module_max_rec_group_size(mod_)
if actual > limit {
return Some(
(
RecGroupSizeBudgetExceeded,
"gen-valid rec-group budget exceeded: actual \{actual}, limit \{limit}",
),
)
}
}
None => ()
}
match config.max_section_count_budget {
Some(limit) => {
let actual = gen_valid_module_section_count(mod_)
if actual > limit {
return Some(
(
SectionCountBudgetExceeded,
"gen-valid section-count budget exceeded: actual \{actual}, limit \{limit}",
),
)
}
}
None => ()
}
let segment_limit = config.max_segment_payload_size
if segment_limit < 0 {
let actual = gen_valid_module_segment_payload_size(mod_)
if actual > segment_limit {
return Some(
(
SegmentPayloadSizeBudgetExceeded,
"gen-valid segment payload budget exceeded: actual \{actual}, limit \{segment_limit}",
),
)
}
}
None
}
///|
pub fn gen_valid_module_result(
rnd : RandomState,
config : GenValidConfig,
) -> Result[GenValidGenerated, GenValidFailure] {
let max_attempts = if config.mode == CoverageForced { 512 } else { 64 }
let config_label = gen_valid_config_label(config)
let mut attempt = 1
let mut last = gen_valid_module_once_with_config(rnd, config)
let mut last_error_message = ""
let mut last_budget_stop = None
while attempt <= max_attempts {
match gen_valid_budget_error(last, config) {
Some((stop, message)) => {
last_budget_stop = Some(stop)
last_error_message = message
}
None =>
match validate_module(last) {
Ok(_) =>
return Ok({
wasm_module: last,
config,
config_label,
attempts: attempt,
facts: gen_valid_feature_facts(last, config.mode),
})
Err(err) => {
last_budget_stop = None
last_error_message = validation_error_message(err)
}
}
}
if attempt < max_attempts {
last = gen_valid_module_once_with_config(rnd, config)
}
attempt += 1
}
Err({
last_candidate: last,
config,
config_label,
attempts: max_attempts,
validation_error_message: last_error_message,
budget_stop: last_budget_stop,
})
}
///|
pub fn gen_valid_module_from_seed(
seed : UInt64,
config : GenValidConfig,
) -> Result[GenValidModuleGenerated, GenValidFailure] {
let max_attempts = if config.mode == CoverageForced { 512 } else { 64 }
let config_label = gen_valid_config_label(config)
let mut attempt = 1
let mut last = gen_valid_module_once_with_stream_seed(seed, config)
let mut last_error_message = ""
let mut last_budget_stop = None
while attempt <= max_attempts {
match gen_valid_budget_error(last, config) {
Some((stop, message)) => {
last_budget_stop = Some(stop)
last_error_message = message
}
None =>
match validate_module(last) {
Ok(_) =>
return Ok({
wasm_module: last,
config,
config_label,
attempts: attempt,
})
Err(err) => {
last_budget_stop = None
last_error_message = validation_error_message(err)
}
}
}
if attempt < max_attempts {
last = gen_valid_module_once_with_stream_seed(
seed ^ attempt.to_uint64(),
config,
)
}
attempt += 1
}
Err({
last_candidate: last,
config,
config_label,
attempts: max_attempts,
validation_error_message: last_error_message,
budget_stop: last_budget_stop,
})
}
///|
pub fn gen_valid_module_result_from_seed(
seed : UInt64,
config : GenValidConfig,
) -> Result[GenValidGenerated, GenValidFailure] {
match gen_valid_module_from_seed(seed, config) {
Ok(generated) =>
Ok({
wasm_module: generated.wasm_module,
config: generated.config,
config_label: generated.config_label,
attempts: generated.attempts,
facts: gen_valid_feature_facts(generated.wasm_module, config.mode),
})
Err(failure) => Err(failure)
}
}
///|
pub fn gen_valid_module_with_config(
rnd : RandomState,
config : GenValidConfig,
) -> Module {
match gen_valid_module_result(rnd, config) {
Ok(generated) => generated.wasm_module
Err(failure) => failure.last_candidate
}
}
///|
pub fn gen_valid_module(rnd : RandomState) -> Module {
gen_valid_module_with_config(rnd, default_gen_valid_config())
}
///|
fn gen_valid_scan_storage_type(storage : StorageType) -> (Bool, Bool) {
match storage {
ValTypeStorageType(vt) => gen_valid_scan_val_type(vt)
PackTypeStorageType(_) => (false, false)
}
}
///|
fn gen_valid_scan_field_type(field : FieldType) -> (Bool, Bool) {
let FieldType(storage, _) = field
gen_valid_scan_storage_type(storage)
}
///|
fn gen_valid_scan_val_type(vt : ValType) -> (Bool, Bool) {
match vt {
VecTypeValType => (false, true)
RefTypeValType(_) => (true, false)
_ => (false, false)
}
}
///|
fn gen_valid_scan_block_type(bt : BlockType) -> (Bool, Bool) {
match bt {
ValTypeBlockType(vt) => gen_valid_scan_val_type(vt)
_ => (false, false)
}
}
///|
fn gen_valid_scan_comp_type(comp : CompType) -> (Bool, Bool) {
match comp {
FuncCompType(params, results) => {
let mut uses_ref_types = false
let mut uses_v128 = false
for vt in params {
let (has_ref, has_v128) = gen_valid_scan_val_type(vt)
uses_ref_types = uses_ref_types || has_ref
uses_v128 = uses_v128 || has_v128
}
for vt in results {
let (has_ref, has_v128) = gen_valid_scan_val_type(vt)
uses_ref_types = uses_ref_types || has_ref
uses_v128 = uses_v128 || has_v128
}
(uses_ref_types, uses_v128)
}
ArrayCompType(field) => gen_valid_scan_field_type(field)
StructCompType(fields) => {
let mut uses_ref_types = false
let mut uses_v128 = false
for field in fields {
let (has_ref, has_v128) = gen_valid_scan_field_type(field)
uses_ref_types = uses_ref_types || has_ref
uses_v128 = uses_v128 || has_v128
}
(uses_ref_types, uses_v128)
}
ContCompType(_) => (true, false)
}
}
///|
fn gen_valid_scan_sub_type(subtype : SubType) -> (Bool, Bool) {
match subtype {
SubType(_, _, _, comp) | CompTypeSubType(_, comp) =>
gen_valid_scan_comp_type(comp)
}
}
///|
fn gen_valid_scan_sub_type_topology(subtype : SubType) -> Bool {
match subtype {
SubType(is_final, supers, _, _) => is_final || !supers.is_empty()
CompTypeSubType(_, _) => false
}
}
///|
fn gen_valid_scan_rec_type_topology(rec_type : RecType) -> Bool {
match rec_type {
SingleRecType(subtype) => gen_valid_scan_sub_type_topology(subtype)
GroupRecType(group) => {
if group.length() >= 3 {
return true
}
for subtype in group {
if gen_valid_scan_sub_type_topology(subtype) {
return true
}
}
false
}
}
}
///|
fn gen_valid_scan_field_plan_rich(fields : Array[FieldType]) -> Bool {
let mut has_packed = false
let mut has_ref = false
let mut has_nonnullable_typed_ref = false
let mut has_const = false
let mut has_var = false
for field in fields {
let FieldType(storage, mut_) = field
match mut_ {
Const => has_const = true
Var => has_var = true
}
match storage {
PackTypeStorageType(_) => has_packed = true
ValTypeStorageType(RefTypeValType(HeapTypeRefType(false, _, HeapType(_)))) => {
has_ref = true
has_nonnullable_typed_ref = true
}
ValTypeStorageType(RefTypeValType(_)) => has_ref = true
_ => ()
}
}
fields.length() >= 4 &&
has_packed &&
has_ref &&
has_nonnullable_typed_ref &&
has_const &&
has_var
}
///|
fn gen_valid_scan_rec_type_rich_gc_field_plan(rec_type : RecType) -> Bool {
fn scan_subtype(subtype : SubType) -> Bool {
match subtype {
SubType(_, _, _, StructCompType(fields))
| CompTypeSubType(_, StructCompType(fields)) =>
gen_valid_scan_field_plan_rich(fields) || fields.length() >= 2
SubType(_, _, _, ArrayCompType(FieldType(PackTypeStorageType(_), _)))
| CompTypeSubType(_, ArrayCompType(FieldType(PackTypeStorageType(_), _)))
| SubType(
_,
_,
_,
ArrayCompType(FieldType(ValTypeStorageType(RefTypeValType(_)), Var))
)
| CompTypeSubType(
_,
ArrayCompType(FieldType(ValTypeStorageType(RefTypeValType(_)), Var))
) => true
_ => false
}
}
match rec_type {
SingleRecType(subtype) => scan_subtype(subtype)
GroupRecType(group) => {
for subtype in group {
if scan_subtype(subtype) {
return true
}
}
false
}
}
}
///|
fn gen_valid_scan_rec_type(rec_type : RecType) -> (Bool, Bool) {
match rec_type {
SingleRecType(subtype) => gen_valid_scan_sub_type(subtype)
GroupRecType(group) => {
let mut uses_ref_types = false
let mut uses_v128 = false
for subtype in group {
let (has_ref, has_v128) = gen_valid_scan_sub_type(subtype)
uses_ref_types = uses_ref_types || has_ref
uses_v128 = uses_v128 || has_v128
}
(uses_ref_types, uses_v128)
}
}
}
///|
fn gen_valid_merge_instr_facts(
left : GenValidInstrFacts,
right : GenValidInstrFacts,
) -> GenValidInstrFacts {
{
uses_ref_types: left.uses_ref_types || right.uses_ref_types,
uses_v128: left.uses_v128 || right.uses_v128,
has_call: left.has_call || right.has_call,
has_call_indirect: left.has_call_indirect || right.has_call_indirect,
has_numeric_full_ops: left.has_numeric_full_ops ||
right.has_numeric_full_ops,
has_br_table: left.has_br_table || right.has_br_table,
has_payload_control_flow: left.has_payload_control_flow ||
right.has_payload_control_flow,
has_multivalue_control_flow: left.has_multivalue_control_flow ||
right.has_multivalue_control_flow,
has_standalone_unreachable: left.has_standalone_unreachable ||
right.has_standalone_unreachable,
has_local_tee: left.has_local_tee || right.has_local_tee,
has_typed_select: left.has_typed_select || right.has_typed_select,
has_tail_calls: left.has_tail_calls || right.has_tail_calls,
has_scalar_memory_widths: left.has_scalar_memory_widths ||
right.has_scalar_memory_widths,
has_nonzero_memarg: left.has_nonzero_memarg || right.has_nonzero_memarg,
has_memory_limit_variants: left.has_memory_limit_variants ||
right.has_memory_limit_variants,
has_basic_ref_instructions: left.has_basic_ref_instructions ||
right.has_basic_ref_instructions,
has_i31_extern_conversions: left.has_i31_extern_conversions ||
right.has_i31_extern_conversions,
has_simd_phase1: left.has_simd_phase1 || right.has_simd_phase1,
has_simd_phase2: left.has_simd_phase2 || right.has_simd_phase2,
has_simd_phase3: left.has_simd_phase3 || right.has_simd_phase3,
has_atomics: left.has_atomics || right.has_atomics,
has_gc_constructors: left.has_gc_constructors || right.has_gc_constructors,
has_gc_accessors: left.has_gc_accessors || right.has_gc_accessors,
has_string_ops: left.has_string_ops || right.has_string_ops,
has_exception_try_table_matrix: left.has_exception_try_table_matrix ||
right.has_exception_try_table_matrix,
has_subtyping_topology: left.has_subtyping_topology ||
right.has_subtyping_topology,
has_rich_gc_field_plans: left.has_rich_gc_field_plans ||
right.has_rich_gc_field_plans,
has_shared_memories: left.has_shared_memories || right.has_shared_memories,
exact_opcode_counts: left.exact_opcode_counts.add(right.exact_opcode_counts),
control_nodes: left.control_nodes + right.control_nodes,
branch_ops: left.branch_ops + right.branch_ops,
}
}
///|
fn gen_valid_block_type_can_produce_values(bt : BlockType) -> Bool {
match bt {
VoidBlockType => false
ValTypeBlockType(_) | TypeIdxBlockType(_) => true
}
}
///|
fn gen_valid_instr_array_has_top_level_branch(
instrs : Array[Instruction],
) -> Bool {
for instr in instrs {
match instr {
Br(_) | BrIf(_) | BrTable(_, _) => return true
_ => ()
}
}
false
}
///|
fn gen_valid_expr_has_top_level_branch(expr : Expr) -> Bool {
let Expr(instrs) = expr
gen_valid_instr_array_has_top_level_branch(instrs)
}
///|
fn gen_valid_exact_opcode_counts_for_instr(
instr : Instruction,
) -> GenValidExactOpcodeCounts {
// Bound default-backend locals: each record update copies 403 fields.
// A single match over every opcode exceeds the engine local-count limit.
let zero = GenValidExactOpcodeCounts::empty()
match instr {
I32Const(_) => GenValidExactOpcodeCounts::{ ..zero, i32_const: 1, }
I64Const(_) => GenValidExactOpcodeCounts::{ ..zero, i64_const: 1, }
F32Const(_) => GenValidExactOpcodeCounts::{ ..zero, f32_const: 1, }
F64Const(_) => GenValidExactOpcodeCounts::{ ..zero, f64_const: 1, }
I32Eqz => GenValidExactOpcodeCounts::{ ..zero, i32_eqz: 1, }
I64Eqz => GenValidExactOpcodeCounts::{ ..zero, i64_eqz: 1, }
I32Eq => GenValidExactOpcodeCounts::{ ..zero, i32_eq: 1, }
I32Ne => GenValidExactOpcodeCounts::{ ..zero, i32_ne: 1, }
I32LtS => GenValidExactOpcodeCounts::{ ..zero, i32_lt_s: 1, }
I32LtU => GenValidExactOpcodeCounts::{ ..zero, i32_lt_u: 1, }
I32GtS => GenValidExactOpcodeCounts::{ ..zero, i32_gt_s: 1, }
I32GtU => GenValidExactOpcodeCounts::{ ..zero, i32_gt_u: 1, }
I32LeS => GenValidExactOpcodeCounts::{ ..zero, i32_le_s: 1, }
I32LeU => GenValidExactOpcodeCounts::{ ..zero, i32_le_u: 1, }
I32GeS => GenValidExactOpcodeCounts::{ ..zero, i32_ge_s: 1, }
I32GeU => GenValidExactOpcodeCounts::{ ..zero, i32_ge_u: 1, }
I64Eq => GenValidExactOpcodeCounts::{ ..zero, i64_eq: 1, }
I64Ne => GenValidExactOpcodeCounts::{ ..zero, i64_ne: 1, }
I64LtS => GenValidExactOpcodeCounts::{ ..zero, i64_lt_s: 1, }
I64LtU => GenValidExactOpcodeCounts::{ ..zero, i64_lt_u: 1, }
I64GtS => GenValidExactOpcodeCounts::{ ..zero, i64_gt_s: 1, }
I64GtU => GenValidExactOpcodeCounts::{ ..zero, i64_gt_u: 1, }
I64LeS => GenValidExactOpcodeCounts::{ ..zero, i64_le_s: 1, }
I64LeU => GenValidExactOpcodeCounts::{ ..zero, i64_le_u: 1, }
I64GeS => GenValidExactOpcodeCounts::{ ..zero, i64_ge_s: 1, }
I64GeU => GenValidExactOpcodeCounts::{ ..zero, i64_ge_u: 1, }
F32Eq => GenValidExactOpcodeCounts::{ ..zero, f32_eq: 1, }
F32Ne => GenValidExactOpcodeCounts::{ ..zero, f32_ne: 1, }
F32Lt => GenValidExactOpcodeCounts::{ ..zero, f32_lt: 1, }
F32Gt => GenValidExactOpcodeCounts::{ ..zero, f32_gt: 1, }
F32Le => GenValidExactOpcodeCounts::{ ..zero, f32_le: 1, }
F32Ge => GenValidExactOpcodeCounts::{ ..zero, f32_ge: 1, }
F64Eq => GenValidExactOpcodeCounts::{ ..zero, f64_eq: 1, }
F64Ne => GenValidExactOpcodeCounts::{ ..zero, f64_ne: 1, }
F64Lt => GenValidExactOpcodeCounts::{ ..zero, f64_lt: 1, }
F64Gt => GenValidExactOpcodeCounts::{ ..zero, f64_gt: 1, }
F64Le => GenValidExactOpcodeCounts::{ ..zero, f64_le: 1, }
F64Ge => GenValidExactOpcodeCounts::{ ..zero, f64_ge: 1, }
I32Clz => GenValidExactOpcodeCounts::{ ..zero, i32_clz: 1, }
I32Ctz => GenValidExactOpcodeCounts::{ ..zero, i32_ctz: 1, }
I32Popcnt => GenValidExactOpcodeCounts::{ ..zero, i32_popcnt: 1, }
I32Add => GenValidExactOpcodeCounts::{ ..zero, i32_add: 1, }
I32Sub => GenValidExactOpcodeCounts::{ ..zero, i32_sub: 1, }
I32Mul => GenValidExactOpcodeCounts::{ ..zero, i32_mul: 1, }
I32DivS => GenValidExactOpcodeCounts::{ ..zero, i32_div_s: 1, }
I32DivU => GenValidExactOpcodeCounts::{ ..zero, i32_div_u: 1, }
I32RemS => GenValidExactOpcodeCounts::{ ..zero, i32_rem_s: 1, }
I32RemU => GenValidExactOpcodeCounts::{ ..zero, i32_rem_u: 1, }
I32And => GenValidExactOpcodeCounts::{ ..zero, i32_and: 1, }
I32Or => GenValidExactOpcodeCounts::{ ..zero, i32_or: 1, }
I32Xor => GenValidExactOpcodeCounts::{ ..zero, i32_xor: 1, }
I32Shl => GenValidExactOpcodeCounts::{ ..zero, i32_shl: 1, }
I32ShrS => GenValidExactOpcodeCounts::{ ..zero, i32_shr_s: 1, }
I32ShrU => GenValidExactOpcodeCounts::{ ..zero, i32_shr_u: 1, }
I32Rotl => GenValidExactOpcodeCounts::{ ..zero, i32_rotl: 1, }
I32Rotr => GenValidExactOpcodeCounts::{ ..zero, i32_rotr: 1, }
I64Clz => GenValidExactOpcodeCounts::{ ..zero, i64_clz: 1, }
I64Ctz => GenValidExactOpcodeCounts::{ ..zero, i64_ctz: 1, }
I64Popcnt => GenValidExactOpcodeCounts::{ ..zero, i64_popcnt: 1, }
I64Add => GenValidExactOpcodeCounts::{ ..zero, i64_add: 1, }
I64Sub => GenValidExactOpcodeCounts::{ ..zero, i64_sub: 1, }
I64Mul => GenValidExactOpcodeCounts::{ ..zero, i64_mul: 1, }
I64DivS => GenValidExactOpcodeCounts::{ ..zero, i64_div_s: 1, }
I64DivU => GenValidExactOpcodeCounts::{ ..zero, i64_div_u: 1, }
_ => gen_valid_exact_opcode_counts_part_2(instr, zero)
}
}
///|
fn gen_valid_exact_opcode_counts_part_2(
instr : Instruction,
zero : GenValidExactOpcodeCounts,
) -> GenValidExactOpcodeCounts {
match instr {
I64RemS => GenValidExactOpcodeCounts::{ ..zero, i64_rem_s: 1, }
I64RemU => GenValidExactOpcodeCounts::{ ..zero, i64_rem_u: 1, }
I64And => GenValidExactOpcodeCounts::{ ..zero, i64_and: 1, }
I64Or => GenValidExactOpcodeCounts::{ ..zero, i64_or: 1, }
I64Xor => GenValidExactOpcodeCounts::{ ..zero, i64_xor: 1, }
I64Shl => GenValidExactOpcodeCounts::{ ..zero, i64_shl: 1, }
I64ShrS => GenValidExactOpcodeCounts::{ ..zero, i64_shr_s: 1, }
I64ShrU => GenValidExactOpcodeCounts::{ ..zero, i64_shr_u: 1, }
I64Rotl => GenValidExactOpcodeCounts::{ ..zero, i64_rotl: 1, }
I64Rotr => GenValidExactOpcodeCounts::{ ..zero, i64_rotr: 1, }
F32Abs => GenValidExactOpcodeCounts::{ ..zero, f32_abs: 1, }
F32Neg => GenValidExactOpcodeCounts::{ ..zero, f32_neg: 1, }
F32Ceil => GenValidExactOpcodeCounts::{ ..zero, f32_ceil: 1, }
F32Floor => GenValidExactOpcodeCounts::{ ..zero, f32_floor: 1, }
F32Trunc => GenValidExactOpcodeCounts::{ ..zero, f32_trunc: 1, }
F32Nearest => GenValidExactOpcodeCounts::{ ..zero, f32_nearest: 1, }
F32Sqrt => GenValidExactOpcodeCounts::{ ..zero, f32_sqrt: 1, }
F32Add => GenValidExactOpcodeCounts::{ ..zero, f32_add: 1, }
F32Sub => GenValidExactOpcodeCounts::{ ..zero, f32_sub: 1, }
F32Mul => GenValidExactOpcodeCounts::{ ..zero, f32_mul: 1, }
F32Div => GenValidExactOpcodeCounts::{ ..zero, f32_div: 1, }
F32Min => GenValidExactOpcodeCounts::{ ..zero, f32_min: 1, }
F32Max => GenValidExactOpcodeCounts::{ ..zero, f32_max: 1, }
F32Copysign => GenValidExactOpcodeCounts::{ ..zero, f32_copysign: 1, }
F64Abs => GenValidExactOpcodeCounts::{ ..zero, f64_abs: 1, }
F64Neg => GenValidExactOpcodeCounts::{ ..zero, f64_neg: 1, }
F64Ceil => GenValidExactOpcodeCounts::{ ..zero, f64_ceil: 1, }
F64Floor => GenValidExactOpcodeCounts::{ ..zero, f64_floor: 1, }
F64Trunc => GenValidExactOpcodeCounts::{ ..zero, f64_trunc: 1, }
F64Nearest => GenValidExactOpcodeCounts::{ ..zero, f64_nearest: 1, }
F64Sqrt => GenValidExactOpcodeCounts::{ ..zero, f64_sqrt: 1, }
F64Add => GenValidExactOpcodeCounts::{ ..zero, f64_add: 1, }
F64Sub => GenValidExactOpcodeCounts::{ ..zero, f64_sub: 1, }
F64Mul => GenValidExactOpcodeCounts::{ ..zero, f64_mul: 1, }
F64Div => GenValidExactOpcodeCounts::{ ..zero, f64_div: 1, }
F64Min => GenValidExactOpcodeCounts::{ ..zero, f64_min: 1, }
F64Max => GenValidExactOpcodeCounts::{ ..zero, f64_max: 1, }
F64Copysign => GenValidExactOpcodeCounts::{ ..zero, f64_copysign: 1, }
I32WrapI64 => GenValidExactOpcodeCounts::{ ..zero, i32_wrap_i64: 1, }
I32TruncF32S => GenValidExactOpcodeCounts::{ ..zero, i32_trunc_f32s: 1, }
I32TruncF32U => GenValidExactOpcodeCounts::{ ..zero, i32_trunc_f32u: 1, }
I32TruncF64S => GenValidExactOpcodeCounts::{ ..zero, i32_trunc_f64s: 1, }
I32TruncF64U => GenValidExactOpcodeCounts::{ ..zero, i32_trunc_f64u: 1, }
I64ExtendI32S => GenValidExactOpcodeCounts::{ ..zero, i64_extend_i32s: 1, }
I64ExtendI32U => GenValidExactOpcodeCounts::{ ..zero, i64_extend_i32u: 1, }
I64TruncF32S => GenValidExactOpcodeCounts::{ ..zero, i64_trunc_f32s: 1, }
I64TruncF32U => GenValidExactOpcodeCounts::{ ..zero, i64_trunc_f32u: 1, }
I64TruncF64S => GenValidExactOpcodeCounts::{ ..zero, i64_trunc_f64s: 1, }
I64TruncF64U => GenValidExactOpcodeCounts::{ ..zero, i64_trunc_f64u: 1, }
F32ConvertI32S =>
GenValidExactOpcodeCounts::{ ..zero, f32_convert_i32s: 1, }
F32ConvertI32U =>
GenValidExactOpcodeCounts::{ ..zero, f32_convert_i32u: 1, }
F32ConvertI64S =>
GenValidExactOpcodeCounts::{ ..zero, f32_convert_i64s: 1, }
F32ConvertI64U =>
GenValidExactOpcodeCounts::{ ..zero, f32_convert_i64u: 1, }
F32DemoteF64 => GenValidExactOpcodeCounts::{ ..zero, f32_demote_f64: 1, }
F64ConvertI32S =>
GenValidExactOpcodeCounts::{ ..zero, f64_convert_i32s: 1, }
F64ConvertI32U =>
GenValidExactOpcodeCounts::{ ..zero, f64_convert_i32u: 1, }
F64ConvertI64S =>
GenValidExactOpcodeCounts::{ ..zero, f64_convert_i64s: 1, }
F64ConvertI64U =>
GenValidExactOpcodeCounts::{ ..zero, f64_convert_i64u: 1, }
F64PromoteF32 => GenValidExactOpcodeCounts::{ ..zero, f64_promote_f32: 1, }
I32Extend8S => GenValidExactOpcodeCounts::{ ..zero, i32_extend8s: 1, }
I32Extend16S => GenValidExactOpcodeCounts::{ ..zero, i32_extend16s: 1, }
I64Extend8S => GenValidExactOpcodeCounts::{ ..zero, i64_extend8s: 1, }
I64Extend16S => GenValidExactOpcodeCounts::{ ..zero, i64_extend16s: 1, }
I64Extend32S => GenValidExactOpcodeCounts::{ ..zero, i64_extend32s: 1, }
_ => gen_valid_exact_opcode_counts_part_3(instr, zero)
}
}
///|
fn gen_valid_exact_opcode_counts_part_3(
instr : Instruction,
zero : GenValidExactOpcodeCounts,
) -> GenValidExactOpcodeCounts {
match instr {
I32TruncSatF32S =>
GenValidExactOpcodeCounts::{ ..zero, i32_trunc_sat_f32s: 1, }
I32TruncSatF32U =>
GenValidExactOpcodeCounts::{ ..zero, i32_trunc_sat_f32u: 1, }
I32TruncSatF64S =>
GenValidExactOpcodeCounts::{ ..zero, i32_trunc_sat_f64s: 1, }
I32TruncSatF64U =>
GenValidExactOpcodeCounts::{ ..zero, i32_trunc_sat_f64u: 1, }
I64TruncSatF32S =>
GenValidExactOpcodeCounts::{ ..zero, i64_trunc_sat_f32s: 1, }
I64TruncSatF32U =>
GenValidExactOpcodeCounts::{ ..zero, i64_trunc_sat_f32u: 1, }
I64TruncSatF64S =>
GenValidExactOpcodeCounts::{ ..zero, i64_trunc_sat_f64s: 1, }
I64TruncSatF64U =>
GenValidExactOpcodeCounts::{ ..zero, i64_trunc_sat_f64u: 1, }
I32ReinterpretF32 =>
GenValidExactOpcodeCounts::{ ..zero, i32_reinterpret_f32: 1, }
I64ReinterpretF64 =>
GenValidExactOpcodeCounts::{ ..zero, i64_reinterpret_f64: 1, }
F32ReinterpretI32 =>
GenValidExactOpcodeCounts::{ ..zero, f32_reinterpret_i32: 1, }
F64ReinterpretI64 =>
GenValidExactOpcodeCounts::{ ..zero, f64_reinterpret_i64: 1, }
BrTable(_, _) => GenValidExactOpcodeCounts::{ ..zero, br_table: 1, }
Unreachable => GenValidExactOpcodeCounts::{ ..zero, unreachable_opcode: 1, }
LocalTee(_) => GenValidExactOpcodeCounts::{ ..zero, local_tee: 1, }
Select(Some(_)) => GenValidExactOpcodeCounts::{ ..zero, typed_select: 1, }
ReturnCall(_) => GenValidExactOpcodeCounts::{ ..zero, return_call: 1, }
ReturnCallIndirect(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, return_call_indirect: 1, }
ReturnCallRef(_) =>
GenValidExactOpcodeCounts::{ ..zero, return_call_ref: 1, }
V128Const(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_const: 1, }
I8x16Splat => GenValidExactOpcodeCounts::{ ..zero, i8x16_splat: 1, }
I16x8Splat => GenValidExactOpcodeCounts::{ ..zero, i16x8_splat: 1, }
I32x4Splat => GenValidExactOpcodeCounts::{ ..zero, i32x4_splat: 1, }
I64x2Splat => GenValidExactOpcodeCounts::{ ..zero, i64x2_splat: 1, }
F32x4Splat => GenValidExactOpcodeCounts::{ ..zero, f32x4_splat: 1, }
F64x2Splat => GenValidExactOpcodeCounts::{ ..zero, f64x2_splat: 1, }
I8x16ExtractLaneS(_) =>
GenValidExactOpcodeCounts::{ ..zero, i8x16_extract_lane_s: 1, }
I8x16ExtractLaneU(_) =>
GenValidExactOpcodeCounts::{ ..zero, i8x16_extract_lane_u: 1, }
I8x16ReplaceLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, i8x16_replace_lane: 1, }
I16x8ExtractLaneS(_) =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extract_lane_s: 1, }
I16x8ExtractLaneU(_) =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extract_lane_u: 1, }
I16x8ReplaceLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_replace_lane: 1, }
I32x4ExtractLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extract_lane: 1, }
I32x4ReplaceLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_replace_lane: 1, }
I64x2ExtractLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extract_lane: 1, }
I64x2ReplaceLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_replace_lane: 1, }
F32x4ExtractLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_extract_lane: 1, }
F32x4ReplaceLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_replace_lane: 1, }
F64x2ExtractLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_extract_lane: 1, }
F64x2ReplaceLane(_) =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_replace_lane: 1, }
V128Not => GenValidExactOpcodeCounts::{ ..zero, v128_not: 1, }
V128And => GenValidExactOpcodeCounts::{ ..zero, v128_and: 1, }
V128Andnot => GenValidExactOpcodeCounts::{ ..zero, v128_andnot: 1, }
V128Or => GenValidExactOpcodeCounts::{ ..zero, v128_or: 1, }
V128Xor => GenValidExactOpcodeCounts::{ ..zero, v128_xor: 1, }
V128Bitselect => GenValidExactOpcodeCounts::{ ..zero, v128_bitselect: 1, }
V128AnyTrue => GenValidExactOpcodeCounts::{ ..zero, v128_any_true: 1, }
I8x16Eq => GenValidExactOpcodeCounts::{ ..zero, i8x16_eq: 1, }
I8x16Ne => GenValidExactOpcodeCounts::{ ..zero, i8x16_ne: 1, }
I8x16LtS => GenValidExactOpcodeCounts::{ ..zero, i8x16_lt_s: 1, }
I8x16LtU => GenValidExactOpcodeCounts::{ ..zero, i8x16_lt_u: 1, }
I8x16GtS => GenValidExactOpcodeCounts::{ ..zero, i8x16_gt_s: 1, }
I8x16GtU => GenValidExactOpcodeCounts::{ ..zero, i8x16_gt_u: 1, }
I8x16LeS => GenValidExactOpcodeCounts::{ ..zero, i8x16_le_s: 1, }
I8x16LeU => GenValidExactOpcodeCounts::{ ..zero, i8x16_le_u: 1, }
I8x16GeS => GenValidExactOpcodeCounts::{ ..zero, i8x16_ge_s: 1, }
I8x16GeU => GenValidExactOpcodeCounts::{ ..zero, i8x16_ge_u: 1, }
I16x8Eq => GenValidExactOpcodeCounts::{ ..zero, i16x8_eq: 1, }
I16x8Ne => GenValidExactOpcodeCounts::{ ..zero, i16x8_ne: 1, }
I16x8LtS => GenValidExactOpcodeCounts::{ ..zero, i16x8_lt_s: 1, }
I16x8LtU => GenValidExactOpcodeCounts::{ ..zero, i16x8_lt_u: 1, }
I16x8GtS => GenValidExactOpcodeCounts::{ ..zero, i16x8_gt_s: 1, }
I16x8GtU => GenValidExactOpcodeCounts::{ ..zero, i16x8_gt_u: 1, }
I16x8LeS => GenValidExactOpcodeCounts::{ ..zero, i16x8_le_s: 1, }
_ => gen_valid_exact_opcode_counts_part_4(instr, zero)
}
}
///|
fn gen_valid_exact_opcode_counts_part_4(
instr : Instruction,
zero : GenValidExactOpcodeCounts,
) -> GenValidExactOpcodeCounts {
match instr {
I16x8LeU => GenValidExactOpcodeCounts::{ ..zero, i16x8_le_u: 1, }
I16x8GeS => GenValidExactOpcodeCounts::{ ..zero, i16x8_ge_s: 1, }
I16x8GeU => GenValidExactOpcodeCounts::{ ..zero, i16x8_ge_u: 1, }
I32x4Eq => GenValidExactOpcodeCounts::{ ..zero, i32x4_eq: 1, }
I32x4Ne => GenValidExactOpcodeCounts::{ ..zero, i32x4_ne: 1, }
I32x4LtS => GenValidExactOpcodeCounts::{ ..zero, i32x4_lt_s: 1, }
I32x4LtU => GenValidExactOpcodeCounts::{ ..zero, i32x4_lt_u: 1, }
I32x4GtS => GenValidExactOpcodeCounts::{ ..zero, i32x4_gt_s: 1, }
I32x4GtU => GenValidExactOpcodeCounts::{ ..zero, i32x4_gt_u: 1, }
I32x4LeS => GenValidExactOpcodeCounts::{ ..zero, i32x4_le_s: 1, }
I32x4LeU => GenValidExactOpcodeCounts::{ ..zero, i32x4_le_u: 1, }
I32x4GeS => GenValidExactOpcodeCounts::{ ..zero, i32x4_ge_s: 1, }
I32x4GeU => GenValidExactOpcodeCounts::{ ..zero, i32x4_ge_u: 1, }
I64x2Eq => GenValidExactOpcodeCounts::{ ..zero, i64x2_eq: 1, }
I64x2Ne => GenValidExactOpcodeCounts::{ ..zero, i64x2_ne: 1, }
I64x2LtS => GenValidExactOpcodeCounts::{ ..zero, i64x2_lt_s: 1, }
I64x2GtS => GenValidExactOpcodeCounts::{ ..zero, i64x2_gt_s: 1, }
I64x2LeS => GenValidExactOpcodeCounts::{ ..zero, i64x2_le_s: 1, }
F32x4Eq => GenValidExactOpcodeCounts::{ ..zero, f32x4_eq: 1, }
F32x4Ne => GenValidExactOpcodeCounts::{ ..zero, f32x4_ne: 1, }
F32x4Lt => GenValidExactOpcodeCounts::{ ..zero, f32x4_lt: 1, }
F32x4Gt => GenValidExactOpcodeCounts::{ ..zero, f32x4_gt: 1, }
F32x4Le => GenValidExactOpcodeCounts::{ ..zero, f32x4_le: 1, }
F32x4Ge => GenValidExactOpcodeCounts::{ ..zero, f32x4_ge: 1, }
F64x2Eq => GenValidExactOpcodeCounts::{ ..zero, f64x2_eq: 1, }
F64x2Ne => GenValidExactOpcodeCounts::{ ..zero, f64x2_ne: 1, }
F64x2Lt => GenValidExactOpcodeCounts::{ ..zero, f64x2_lt: 1, }
F64x2Gt => GenValidExactOpcodeCounts::{ ..zero, f64x2_gt: 1, }
F64x2Le => GenValidExactOpcodeCounts::{ ..zero, f64x2_le: 1, }
F64x2Ge => GenValidExactOpcodeCounts::{ ..zero, f64x2_ge: 1, }
I8x16Abs => GenValidExactOpcodeCounts::{ ..zero, i8x16_abs: 1, }
I8x16Neg => GenValidExactOpcodeCounts::{ ..zero, i8x16_neg: 1, }
I8x16Popcnt => GenValidExactOpcodeCounts::{ ..zero, i8x16_popcnt: 1, }
I8x16AllTrue => GenValidExactOpcodeCounts::{ ..zero, i8x16_all_true: 1, }
I8x16Bitmask => GenValidExactOpcodeCounts::{ ..zero, i8x16_bitmask: 1, }
I16x8Abs => GenValidExactOpcodeCounts::{ ..zero, i16x8_abs: 1, }
I16x8Neg => GenValidExactOpcodeCounts::{ ..zero, i16x8_neg: 1, }
I16x8Q15mulrSatS =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_q15mulr_sat_s: 1, }
I16x8AllTrue => GenValidExactOpcodeCounts::{ ..zero, i16x8_all_true: 1, }
I16x8Bitmask => GenValidExactOpcodeCounts::{ ..zero, i16x8_bitmask: 1, }
I32x4Abs => GenValidExactOpcodeCounts::{ ..zero, i32x4_abs: 1, }
I32x4Neg => GenValidExactOpcodeCounts::{ ..zero, i32x4_neg: 1, }
I32x4Bitmask => GenValidExactOpcodeCounts::{ ..zero, i32x4_bitmask: 1, }
I64x2Abs => GenValidExactOpcodeCounts::{ ..zero, i64x2_abs: 1, }
I64x2Neg => GenValidExactOpcodeCounts::{ ..zero, i64x2_neg: 1, }
I64x2AllTrue => GenValidExactOpcodeCounts::{ ..zero, i64x2_all_true: 1, }
I8x16Add => GenValidExactOpcodeCounts::{ ..zero, i8x16_add: 1, }
I8x16AddSatS => GenValidExactOpcodeCounts::{ ..zero, i8x16_add_sat_s: 1, }
I8x16AddSatU => GenValidExactOpcodeCounts::{ ..zero, i8x16_add_sat_u: 1, }
I8x16Sub => GenValidExactOpcodeCounts::{ ..zero, i8x16_sub: 1, }
I8x16SubSatS => GenValidExactOpcodeCounts::{ ..zero, i8x16_sub_sat_s: 1, }
I16x8Mul => GenValidExactOpcodeCounts::{ ..zero, i16x8_mul: 1, }
I8x16Shl => GenValidExactOpcodeCounts::{ ..zero, i8x16_shl: 1, }
I8x16ShrS => GenValidExactOpcodeCounts::{ ..zero, i8x16_shr_s: 1, }
I8x16ShrU => GenValidExactOpcodeCounts::{ ..zero, i8x16_shr_u: 1, }
I16x8Shl => GenValidExactOpcodeCounts::{ ..zero, i16x8_shl: 1, }
I16x8ShrS => GenValidExactOpcodeCounts::{ ..zero, i16x8_shr_s: 1, }
I16x8ShrU => GenValidExactOpcodeCounts::{ ..zero, i16x8_shr_u: 1, }
I32x4Shl => GenValidExactOpcodeCounts::{ ..zero, i32x4_shl: 1, }
I32x4ShrS => GenValidExactOpcodeCounts::{ ..zero, i32x4_shr_s: 1, }
I32x4ShrU => GenValidExactOpcodeCounts::{ ..zero, i32x4_shr_u: 1, }
I64x2Shl => GenValidExactOpcodeCounts::{ ..zero, i64x2_shl: 1, }
I64x2ShrS => GenValidExactOpcodeCounts::{ ..zero, i64x2_shr_s: 1, }
I64x2ShrU => GenValidExactOpcodeCounts::{ ..zero, i64x2_shr_u: 1, }
_ => gen_valid_exact_opcode_counts_part_5(instr, zero)
}
}
///|
fn gen_valid_exact_opcode_counts_part_5(
instr : Instruction,
zero : GenValidExactOpcodeCounts,
) -> GenValidExactOpcodeCounts {
match instr {
I64x2GeS => GenValidExactOpcodeCounts::{ ..zero, i64x2_ge_s: 1, }
I32x4AllTrue => GenValidExactOpcodeCounts::{ ..zero, i32x4_all_true: 1, }
I64x2Bitmask => GenValidExactOpcodeCounts::{ ..zero, i64x2_bitmask: 1, }
I8x16SubSatU => GenValidExactOpcodeCounts::{ ..zero, i8x16_sub_sat_u: 1, }
I8x16MinS => GenValidExactOpcodeCounts::{ ..zero, i8x16_min_s: 1, }
I8x16MinU => GenValidExactOpcodeCounts::{ ..zero, i8x16_min_u: 1, }
I8x16MaxS => GenValidExactOpcodeCounts::{ ..zero, i8x16_max_s: 1, }
I8x16MaxU => GenValidExactOpcodeCounts::{ ..zero, i8x16_max_u: 1, }
I8x16AvgrU => GenValidExactOpcodeCounts::{ ..zero, i8x16_avgr_u: 1, }
I16x8Add => GenValidExactOpcodeCounts::{ ..zero, i16x8_add: 1, }
I16x8AddSatS => GenValidExactOpcodeCounts::{ ..zero, i16x8_add_sat_s: 1, }
I16x8AddSatU => GenValidExactOpcodeCounts::{ ..zero, i16x8_add_sat_u: 1, }
I16x8Sub => GenValidExactOpcodeCounts::{ ..zero, i16x8_sub: 1, }
I16x8SubSatS => GenValidExactOpcodeCounts::{ ..zero, i16x8_sub_sat_s: 1, }
I16x8SubSatU => GenValidExactOpcodeCounts::{ ..zero, i16x8_sub_sat_u: 1, }
I16x8MinS => GenValidExactOpcodeCounts::{ ..zero, i16x8_min_s: 1, }
I16x8MinU => GenValidExactOpcodeCounts::{ ..zero, i16x8_min_u: 1, }
I16x8MaxS => GenValidExactOpcodeCounts::{ ..zero, i16x8_max_s: 1, }
I16x8MaxU => GenValidExactOpcodeCounts::{ ..zero, i16x8_max_u: 1, }
I16x8AvgrU => GenValidExactOpcodeCounts::{ ..zero, i16x8_avgr_u: 1, }
I32x4Add => GenValidExactOpcodeCounts::{ ..zero, i32x4_add: 1, }
I32x4Sub => GenValidExactOpcodeCounts::{ ..zero, i32x4_sub: 1, }
I32x4Mul => GenValidExactOpcodeCounts::{ ..zero, i32x4_mul: 1, }
I32x4MinS => GenValidExactOpcodeCounts::{ ..zero, i32x4_min_s: 1, }
I32x4MinU => GenValidExactOpcodeCounts::{ ..zero, i32x4_min_u: 1, }
I32x4MaxS => GenValidExactOpcodeCounts::{ ..zero, i32x4_max_s: 1, }
I32x4MaxU => GenValidExactOpcodeCounts::{ ..zero, i32x4_max_u: 1, }
I64x2Add => GenValidExactOpcodeCounts::{ ..zero, i64x2_add: 1, }
I64x2Sub => GenValidExactOpcodeCounts::{ ..zero, i64x2_sub: 1, }
I64x2Mul => GenValidExactOpcodeCounts::{ ..zero, i64x2_mul: 1, }
F32x4Add => GenValidExactOpcodeCounts::{ ..zero, f32x4_add: 1, }
F32x4Abs => GenValidExactOpcodeCounts::{ ..zero, f32x4_abs: 1, }
F32x4Neg => GenValidExactOpcodeCounts::{ ..zero, f32x4_neg: 1, }
F32x4Sqrt => GenValidExactOpcodeCounts::{ ..zero, f32x4_sqrt: 1, }
F32x4Sub => GenValidExactOpcodeCounts::{ ..zero, f32x4_sub: 1, }
F32x4Mul => GenValidExactOpcodeCounts::{ ..zero, f32x4_mul: 1, }
F32x4Div => GenValidExactOpcodeCounts::{ ..zero, f32x4_div: 1, }
F32x4Min => GenValidExactOpcodeCounts::{ ..zero, f32x4_min: 1, }
F32x4Max => GenValidExactOpcodeCounts::{ ..zero, f32x4_max: 1, }
F32x4Pmin => GenValidExactOpcodeCounts::{ ..zero, f32x4_pmin: 1, }
F32x4Pmax => GenValidExactOpcodeCounts::{ ..zero, f32x4_pmax: 1, }
F64x2Add => GenValidExactOpcodeCounts::{ ..zero, f64x2_add: 1, }
F64x2Abs => GenValidExactOpcodeCounts::{ ..zero, f64x2_abs: 1, }
F64x2Neg => GenValidExactOpcodeCounts::{ ..zero, f64x2_neg: 1, }
F64x2Sqrt => GenValidExactOpcodeCounts::{ ..zero, f64x2_sqrt: 1, }
F64x2Sub => GenValidExactOpcodeCounts::{ ..zero, f64x2_sub: 1, }
F64x2Mul => GenValidExactOpcodeCounts::{ ..zero, f64x2_mul: 1, }
F64x2Div => GenValidExactOpcodeCounts::{ ..zero, f64x2_div: 1, }
F64x2Min => GenValidExactOpcodeCounts::{ ..zero, f64x2_min: 1, }
F64x2Max => GenValidExactOpcodeCounts::{ ..zero, f64x2_max: 1, }
F64x2Pmin => GenValidExactOpcodeCounts::{ ..zero, f64x2_pmin: 1, }
F64x2Pmax => GenValidExactOpcodeCounts::{ ..zero, f64x2_pmax: 1, }
F32x4Ceil => GenValidExactOpcodeCounts::{ ..zero, f32x4_ceil: 1, }
F32x4Floor => GenValidExactOpcodeCounts::{ ..zero, f32x4_floor: 1, }
F32x4Trunc => GenValidExactOpcodeCounts::{ ..zero, f32x4_trunc: 1, }
F32x4Nearest => GenValidExactOpcodeCounts::{ ..zero, f32x4_nearest: 1, }
F64x2Ceil => GenValidExactOpcodeCounts::{ ..zero, f64x2_ceil: 1, }
F64x2Floor => GenValidExactOpcodeCounts::{ ..zero, f64x2_floor: 1, }
F64x2Trunc => GenValidExactOpcodeCounts::{ ..zero, f64x2_trunc: 1, }
F64x2Nearest => GenValidExactOpcodeCounts::{ ..zero, f64x2_nearest: 1, }
V128Load8x8S(_) => GenValidExactOpcodeCounts::{ ..zero, v128_load8x8_s: 1, }
V128Load8x8U(_) => GenValidExactOpcodeCounts::{ ..zero, v128_load8x8_u: 1, }
V128Load16x4S(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load16x4_s: 1, }
V128Load16x4U(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load16x4_u: 1, }
_ => gen_valid_exact_opcode_counts_part_6(instr, zero)
}
}
///|
fn gen_valid_exact_opcode_counts_part_6(
instr : Instruction,
zero : GenValidExactOpcodeCounts,
) -> GenValidExactOpcodeCounts {
match instr {
V128Load32x2S(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load32x2_s: 1, }
V128Load32x2U(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load32x2_u: 1, }
V128Load8Splat(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load8_splat: 1, }
V128Load16Splat(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load16_splat: 1, }
V128Load32Splat(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load32_splat: 1, }
V128Load64Splat(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load64_splat: 1, }
V128Load8Lane(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load8_lane: 1, }
V128Load16Lane(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load16_lane: 1, }
V128Load32Lane(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load32_lane: 1, }
V128Load64Lane(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load64_lane: 1, }
V128Store8Lane(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_store8_lane: 1, }
V128Store16Lane(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_store16_lane: 1, }
V128Store32Lane(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_store32_lane: 1, }
V128Store64Lane(_, _) =>
GenValidExactOpcodeCounts::{ ..zero, v128_store64_lane: 1, }
V128Load32Zero(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load32_zero: 1, }
V128Load64Zero(_) =>
GenValidExactOpcodeCounts::{ ..zero, v128_load64_zero: 1, }
I8x16NarrowI16x8U =>
GenValidExactOpcodeCounts::{ ..zero, i8x16_narrow_i16x8_u: 1, }
I16x8NarrowI32x4S =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_narrow_i32x4_s: 1, }
I16x8NarrowI32x4U =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_narrow_i32x4_u: 1, }
I16x8ExtaddPairwiseI8x16S =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extadd_pairwise_i8x16_s: 1, }
I16x8ExtaddPairwiseI8x16U =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extadd_pairwise_i8x16_u: 1, }
I32x4ExtaddPairwiseI16x8S =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extadd_pairwise_i16x8_s: 1, }
I32x4ExtaddPairwiseI16x8U =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extadd_pairwise_i16x8_u: 1, }
I16x8ExtendLowI8x16S =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extend_low_i8x16_s: 1, }
I16x8ExtendHighI8x16S =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extend_high_i8x16_s: 1, }
I16x8ExtendLowI8x16U =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extend_low_i8x16_u: 1, }
I16x8ExtendHighI8x16U =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extend_high_i8x16_u: 1, }
I32x4ExtendLowI16x8S =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extend_low_i16x8_s: 1, }
I32x4ExtendHighI16x8S =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extend_high_i16x8_s: 1, }
I32x4ExtendLowI16x8U =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extend_low_i16x8_u: 1, }
I32x4ExtendHighI16x8U =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extend_high_i16x8_u: 1, }
I64x2ExtendLowI32x4S =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extend_low_i32x4_s: 1, }
I64x2ExtendHighI32x4S =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extend_high_i32x4_s: 1, }
I64x2ExtendLowI32x4U =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extend_low_i32x4_u: 1, }
I64x2ExtendHighI32x4U =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extend_high_i32x4_u: 1, }
I16x8ExtmulLowI8x16S =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extmul_low_i8x16_s: 1, }
I16x8ExtmulHighI8x16S =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extmul_high_i8x16_s: 1, }
I16x8ExtmulLowI8x16U =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extmul_low_i8x16_u: 1, }
I16x8ExtmulHighI8x16U =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_extmul_high_i8x16_u: 1, }
I32x4ExtmulLowI16x8S =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extmul_low_i16x8_s: 1, }
I32x4ExtmulHighI16x8S =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extmul_high_i16x8_s: 1, }
I32x4ExtmulLowI16x8U =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extmul_low_i16x8_u: 1, }
I32x4ExtmulHighI16x8U =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_extmul_high_i16x8_u: 1, }
I64x2ExtmulLowI32x4S =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extmul_low_i32x4_s: 1, }
I64x2ExtmulHighI32x4S =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extmul_high_i32x4_s: 1, }
I64x2ExtmulLowI32x4U =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extmul_low_i32x4_u: 1, }
I64x2ExtmulHighI32x4U =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_extmul_high_i32x4_u: 1, }
F64x2PromoteLowF32x4 =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_promote_low_f32x4: 1, }
V128Load(_) => GenValidExactOpcodeCounts::{ ..zero, v128_load: 1, }
V128Store(_) => GenValidExactOpcodeCounts::{ ..zero, v128_store: 1, }
I8x16Shuffle(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) =>
GenValidExactOpcodeCounts::{ ..zero, i8x16_shuffle: 1, }
I8x16Swizzle => GenValidExactOpcodeCounts::{ ..zero, i8x16_swizzle: 1, }
I8x16NarrowI16x8S =>
GenValidExactOpcodeCounts::{ ..zero, i8x16_narrow_i16x8_s: 1, }
I32x4DotI16x8S =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_dot_i16x8_s: 1, }
F32x4DemoteF64x2Zero =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_demote_f64x2_zero: 1, }
I32x4TruncSatF32x4S =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_trunc_sat_f32x4_s: 1, }
I32x4TruncSatF32x4U =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_trunc_sat_f32x4_u: 1, }
F32x4ConvertI32x4S =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_convert_i32x4_s: 1, }
F32x4ConvertI32x4U =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_convert_i32x4_u: 1, }
I32x4TruncSatF64x2SZero =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_trunc_sat_f64x2_s_zero: 1, }
I32x4TruncSatF64x2UZero =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_trunc_sat_f64x2_u_zero: 1, }
F64x2ConvertLowI32x4S =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_convert_low_i32x4_s: 1, }
F64x2ConvertLowI32x4U =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_convert_low_i32x4_u: 1, }
I8x16RelaxedSwizzle =>
GenValidExactOpcodeCounts::{ ..zero, i8x16_relaxed_swizzle: 1, }
_ => gen_valid_exact_opcode_counts_part_7(instr, zero)
}
}
///|
fn gen_valid_exact_opcode_counts_part_7(
instr : Instruction,
zero : GenValidExactOpcodeCounts,
) -> GenValidExactOpcodeCounts {
match instr {
I32x4RelaxedTruncF32x4S =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_relaxed_trunc_f32x4_s: 1, }
I32x4RelaxedTruncF32x4U =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_relaxed_trunc_f32x4_u: 1, }
I32x4RelaxedTruncZeroF64x2S =>
GenValidExactOpcodeCounts::{
..zero,
i32x4_relaxed_trunc_zero_f64x2_s: 1,
}
I32x4RelaxedTruncZeroF64x2U =>
GenValidExactOpcodeCounts::{
..zero,
i32x4_relaxed_trunc_zero_f64x2_u: 1,
}
F32x4RelaxedMadd =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_relaxed_madd: 1, }
F32x4RelaxedNmadd =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_relaxed_nmadd: 1, }
F64x2RelaxedMadd =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_relaxed_madd: 1, }
F64x2RelaxedNmadd =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_relaxed_nmadd: 1, }
I8x16RelaxedLaneselect =>
GenValidExactOpcodeCounts::{ ..zero, i8x16_relaxed_laneselect: 1, }
I16x8RelaxedLaneselect =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_relaxed_laneselect: 1, }
I32x4RelaxedLaneselect =>
GenValidExactOpcodeCounts::{ ..zero, i32x4_relaxed_laneselect: 1, }
I64x2RelaxedLaneselect =>
GenValidExactOpcodeCounts::{ ..zero, i64x2_relaxed_laneselect: 1, }
F32x4RelaxedMin =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_relaxed_min: 1, }
F32x4RelaxedMax =>
GenValidExactOpcodeCounts::{ ..zero, f32x4_relaxed_max: 1, }
F64x2RelaxedMin =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_relaxed_min: 1, }
F64x2RelaxedMax =>
GenValidExactOpcodeCounts::{ ..zero, f64x2_relaxed_max: 1, }
I16x8RelaxedQ15mulrS =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_relaxed_q15mulr_s: 1, }
I16x8RelaxedDotI8x16I7x16S =>
GenValidExactOpcodeCounts::{ ..zero, i16x8_relaxed_dot_i8x16_i7x16_s: 1, }
I32x4RelaxedDotI8x16I7x16AddS =>
GenValidExactOpcodeCounts::{
..zero,
i32x4_relaxed_dot_i8x16_i7x16_add_s: 1,
}
_ => zero
}
}
///|
fn gen_valid_scan_expr(expr : Expr) -> GenValidInstrFacts {
let Expr(instrs) = expr
let mut facts = GenValidInstrFacts::empty()
for instr in instrs {
facts = gen_valid_merge_instr_facts(facts, gen_valid_scan_instr(instr))
}
facts
}
///|
fn gen_valid_instr_is_simd_phase1(instr : Instruction) -> Bool {
match instr {
V128Const(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _)
| I8x16Splat
| I16x8Splat
| I32x4Splat
| I64x2Splat
| F32x4Splat
| F64x2Splat
| I8x16ExtractLaneS(_)
| I8x16ExtractLaneU(_)
| I8x16ReplaceLane(_)
| I16x8ExtractLaneS(_)
| I16x8ExtractLaneU(_)
| I16x8ReplaceLane(_)
| I32x4ExtractLane(_)
| I32x4ReplaceLane(_)
| I64x2ExtractLane(_)
| I64x2ReplaceLane(_)
| F32x4ExtractLane(_)
| F32x4ReplaceLane(_)
| F64x2ExtractLane(_)
| F64x2ReplaceLane(_)
| V128Not
| V128And
| V128Andnot
| V128Or
| V128Xor
| V128Bitselect
| V128AnyTrue => true
_ => false
}
}
///|
fn gen_valid_instr_is_simd_phase2(instr : Instruction) -> Bool {
match instr {
I8x16Eq
| I8x16Ne
| I8x16LtS
| I8x16LtU
| I8x16GtS
| I8x16GtU
| I8x16LeS
| I8x16LeU
| I8x16GeS
| I8x16GeU
| I16x8LtS
| I16x8GeU
| I32x4GtU
| I32x4LeS
| I64x2Eq
| I64x2GeS
| F32x4Lt
| F32x4Ge
| F64x2Eq
| F64x2Ge
| I8x16Abs
| I8x16Neg
| I8x16Popcnt
| I8x16AllTrue
| I8x16Bitmask
| I16x8Abs
| I16x8Neg
| I16x8Q15mulrSatS
| I16x8AllTrue
| I16x8Bitmask
| I32x4Abs
| I32x4Neg
| I32x4Bitmask
| I64x2Abs
| I64x2Neg
| I64x2AllTrue
| I32x4AllTrue
| I64x2Bitmask
| I8x16Add
| I8x16AddSatS
| I8x16SubSatU
| I8x16MinS
| I8x16MaxU
| I8x16AvgrU
| I16x8Mul
| I8x16Shl
| I8x16ShrS
| I8x16ShrU
| I16x8Shl
| I16x8ShrS
| I16x8ShrU
| I32x4Shl
| I32x4ShrS
| I32x4ShrU
| I64x2Shl
| I64x2ShrS
| I64x2ShrU
| I16x8AddSatU
| I16x8SubSatS
| I16x8MinU
| I16x8MaxS
| I16x8AvgrU
| I32x4Add
| I32x4Mul
| I32x4MinS
| I32x4MaxU
| I64x2Add
| I64x2Mul
| F32x4Add
| F32x4Div
| F32x4Min
| F32x4Max
| F64x2Add
| F64x2Div
| F64x2Min
| F64x2Max
| F32x4Ceil
| F32x4Floor
| F32x4Trunc
| F32x4Nearest
| F64x2Ceil
| F64x2Floor
| F64x2Trunc
| F64x2Nearest => true
_ => false
}
}
///|
fn gen_valid_instr_is_expanded_scalar_numeric(instr : Instruction) -> Bool {
match instr {
I32Eqz
| I32Eq
| I32Ne
| I32LtS
| I32LtU
| I32GtS
| I32GtU
| I32LeS
| I32LeU
| I32GeS
| I32GeU
| I64Eqz
| I64Eq
| I64Ne
| I64LtS
| I64LtU
| I64GtS
| I64GtU
| I64LeS
| I64LeU
| I64GeS
| I64GeU
| F32Eq
| F32Ne
| F32Lt
| F32Gt
| F32Le
| F32Ge
| F64Eq
| F64Ne
| F64Lt
| F64Gt
| F64Le
| F64Ge
| I32DivS
| I32DivU
| I32RemS
| I32RemU
| I32Shl
| I32ShrS
| I32ShrU
| I32Rotl
| I32Rotr
| I64DivS
| I64DivU
| I64RemS
| I64RemU
| I64Shl
| I64ShrS
| I64ShrU
| I64Rotl
| I64Rotr
| F32Ceil
| F32Floor
| F32Trunc
| F32Nearest
| F32Sqrt
| F32Min
| F32Max
| F32Copysign
| F64Ceil
| F64Floor
| F64Trunc
| F64Nearest
| F64Sqrt
| F64Min
| F64Max
| F64Copysign
| I32TruncF32U
| I32TruncF64U
| I64ExtendI32U
| I64TruncF32U
| I64TruncF64U
| F32ConvertI32U
| F32ConvertI64U
| F64ConvertI32U
| F64ConvertI64U
| I32Extend8S
| I32Extend16S
| I64Extend8S
| I64Extend16S
| I64Extend32S
| I32TruncSatF32S
| I32TruncSatF32U
| I32TruncSatF64S
| I32TruncSatF64U
| I64TruncSatF32S
| I64TruncSatF32U
| I64TruncSatF64S
| I64TruncSatF64U => true
_ => false
}
}
///|
fn gen_valid_instr_is_simd_phase3(instr : Instruction) -> Bool {
match instr {
V128Load(_)
| V128Load8x8S(_)
| V128Load8x8U(_)
| V128Load16x4S(_)
| V128Load16x4U(_)
| V128Load32x2S(_)
| V128Load32x2U(_)
| V128Load8Splat(_)
| V128Load16Splat(_)
| V128Load32Splat(_)
| V128Load64Splat(_)
| V128Store(_)
| V128Load8Lane(_, _)
| V128Load16Lane(_, _)
| V128Load32Lane(_, _)
| V128Load64Lane(_, _)
| V128Store8Lane(_, _)
| V128Store16Lane(_, _)
| V128Store32Lane(_, _)
| V128Store64Lane(_, _)
| V128Load32Zero(_)
| V128Load64Zero(_)
| I8x16Shuffle(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _)
| I8x16Swizzle
| I8x16NarrowI16x8S
| I8x16NarrowI16x8U
| I16x8NarrowI32x4S
| I16x8NarrowI32x4U
| I16x8ExtaddPairwiseI8x16S
| I16x8ExtaddPairwiseI8x16U
| I32x4ExtaddPairwiseI16x8S
| I32x4ExtaddPairwiseI16x8U
| I32x4DotI16x8S
| F32x4DemoteF64x2Zero
| F64x2PromoteLowF32x4 => true
_ => false
}
}
///|
fn gen_valid_instr_is_atomic(instr : Instruction) -> Bool {
match instr {
MemoryAtomicNotify(_)
| MemoryAtomicWait32(_)
| MemoryAtomicWait64(_)
| AtomicFence(_)
| I32AtomicLoad(_, _)
| I64AtomicLoad(_, _)
| I32AtomicLoad8U(_, _)
| I32AtomicLoad16U(_, _)
| I64AtomicLoad8U(_, _)
| I64AtomicLoad16U(_, _)
| I64AtomicLoad32U(_, _)
| I32AtomicStore(_, _)
| I64AtomicStore(_, _)
| I32AtomicStore8(_, _)
| I32AtomicStore16(_, _)
| I64AtomicStore8(_, _)
| I64AtomicStore16(_, _)
| I64AtomicStore32(_, _)
| AtomicRmw(_, _, _)
| AtomicCmpxchg(_, _, _)
| StructAtomicGet(_, _, _)
| StructAtomicGetS(_, _, _)
| StructAtomicGetU(_, _, _)
| StructAtomicRmw(_, _, _, _)
| StructAtomicCmpxchg(_, _, _)
| StructAtomicSet(_, _, _)
| ArrayAtomicGet(_, _)
| ArrayAtomicGetS(_, _)
| ArrayAtomicGetU(_, _)
| ArrayAtomicSet(_, _)
| ArrayAtomicRmw(_, _, _)
| ArrayAtomicCmpxchg(_, _) => true
_ => false
}
}
///|
fn gen_valid_memarg_is_nonzero(ma : MemArg) -> Bool {
let MemArg(U32(align_pow), _, U64(offset)) = ma
align_pow.reinterpret_as_int() > 0 || offset > 0
}
///|
fn gen_valid_scan_scalar_memory_instr(
ma : MemArg,
narrow : Bool,
) -> GenValidInstrFacts {
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_scalar_memory_widths: narrow,
has_nonzero_memarg: gen_valid_memarg_is_nonzero(ma),
}
}
///|
fn gen_valid_mem_type_has_limit_variant(mt : MemType) -> Bool {
let MemType(lim, shared) = mt
match lim {
I32Limits(min, max) => min == 0 || max is None || shared
I64Limits(_) => true
}
}
///|
fn gen_valid_mem_type_is_shared(mt : MemType) -> Bool {
let MemType(_, shared) = mt
shared
}
///|
fn gen_valid_table_type_has_limit_variant(
table_type : TableType,
init_opt : Expr?,
) -> Bool {
let TableType(rt, lim) = table_type
let limit_variant = match lim {
I32Limits(min, max) => min == 0 || max is None
I64Limits(min, max) => min == 0UL || max is None
}
limit_variant ||
ValType::ref_type(rt) != ValType::funcref() ||
init_opt is Some(_)
}
///|
fn gen_valid_const_expr_has_variant(expr : Expr) -> Bool {
let Expr(instrs) = expr
for instr in instrs {
match instr {
GlobalGet(_)
| RefFunc(_)
| StructNew(_)
| StructNewDefault(_)
| StructNewDesc(_)
| StructNewDefaultDesc(_)
| ArrayNew(_)
| ArrayNewDefault(_)
| ArrayNewFixed(_, _) => return true
_ => ()
}
}
false
}
///|
fn gen_valid_instr_is_gc_constructor(instr : Instruction) -> Bool {
match instr {
StructNew(_)
| StructNewDefault(_)
| StructNewDesc(_)
| StructNewDefaultDesc(_)
| ArrayNew(_)
| ArrayNewDefault(_)
| ArrayNewFixed(_, _)
| ArrayNewData(_, _)
| ArrayNewElem(_, _) => true
_ => false
}
}
///|
fn gen_valid_instr_is_gc_accessor(instr : Instruction) -> Bool {
match instr {
StructGet(_, _)
| StructGetS(_, _)
| StructGetU(_, _)
| StructSet(_, _)
| ArrayGet(_)
| ArrayGetS(_)
| ArrayGetU(_)
| ArraySet(_)
| ArrayLen
| ArrayFill(_)
| ArrayCopy(_, _)
| ArrayInitData(_, _)
| ArrayInitElem(_, _) => true
_ => false
}
}
///|
fn gen_valid_instr_is_basic_ref_instruction(instr : Instruction) -> Bool {
match instr {
RefNull(rt) =>
match rt.get_heap_type() {
AbsHeapTypeHeapType(NoneAbsHeapType)
| AbsHeapTypeHeapType(NoFuncAbsHeapType)
| AbsHeapTypeHeapType(NoExternAbsHeapType) => true
_ => false
}
RefIsNull
| RefTest(_, _, _)
| RefCast(_, _, _)
| BrOnCast(_, _, _, _)
| BrOnCastFail(_, _, _, _) => true
_ => false
}
}
///|
fn gen_valid_scan_instr(instr : Instruction) -> GenValidInstrFacts {
let exact_opcode_counts = gen_valid_exact_opcode_counts_for_instr(instr)
if gen_valid_exact_opcode_counts_nonzero(exact_opcode_counts) {
return GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_numeric_full_ops: gen_valid_instr_is_expanded_scalar_numeric(instr),
has_br_table: instr is BrTable(_, _),
has_standalone_unreachable: instr is Unreachable,
has_local_tee: instr is LocalTee(_),
has_typed_select: instr is Select(Some(_)),
has_tail_calls: match instr {
ReturnCall(_) | ReturnCallIndirect(_, _) | ReturnCallRef(_) => true
_ => false
},
uses_v128: gen_valid_instr_is_simd_phase1(instr) ||
gen_valid_instr_is_simd_phase2(instr) ||
gen_valid_instr_is_simd_phase3(instr),
has_simd_phase1: gen_valid_instr_is_simd_phase1(instr),
has_simd_phase2: gen_valid_instr_is_simd_phase2(instr),
has_simd_phase3: gen_valid_instr_is_simd_phase3(instr),
exact_opcode_counts,
}
}
if gen_valid_instr_is_simd_phase1(instr) {
return GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_v128: true,
has_simd_phase1: true,
}
}
if gen_valid_instr_is_simd_phase2(instr) {
return GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_v128: true,
has_simd_phase2: true,
}
}
if gen_valid_instr_is_simd_phase3(instr) {
return GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_v128: true,
has_simd_phase3: true,
}
}
if gen_valid_instr_is_atomic(instr) {
return GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_atomics: true,
}
}
if gen_valid_instr_is_expanded_scalar_numeric(instr) {
return GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_numeric_full_ops: true,
}
}
if gen_valid_instr_is_gc_constructor(instr) {
return GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
has_gc_constructors: true,
}
}
if gen_valid_instr_is_gc_accessor(instr) {
return GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
has_gc_accessors: true,
}
}
match instr {
Call(_) =>
GenValidInstrFacts::{ ..GenValidInstrFacts::empty(), has_call: true, }
ReturnCall(_) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_call: true,
has_tail_calls: true,
branch_ops: 1,
}
CallIndirect(_, _) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_call_indirect: true,
branch_ops: 1,
}
ReturnCallIndirect(_, _) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_call_indirect: true,
has_tail_calls: true,
branch_ops: 1,
}
CallRef(_) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
has_call_indirect: true,
branch_ops: 1,
}
ReturnCallRef(_) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
has_call_indirect: true,
has_tail_calls: true,
branch_ops: 1,
}
Br(_) | BrIf(_) =>
GenValidInstrFacts::{ ..GenValidInstrFacts::empty(), branch_ops: 1, }
BrTable(_, _) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_br_table: true,
branch_ops: 1,
}
I32Load(ma)
| I64Load(ma)
| F32Load(ma)
| F64Load(ma)
| I32Store(ma)
| I64Store(ma)
| F32Store(ma)
| F64Store(ma) => gen_valid_scan_scalar_memory_instr(ma, false)
I32Load8S(ma)
| I32Load8U(ma)
| I32Load16S(ma)
| I32Load16U(ma)
| I64Load8S(ma)
| I64Load8U(ma)
| I64Load16S(ma)
| I64Load16U(ma)
| I64Load32S(ma)
| I64Load32U(ma)
| I32Store8(ma)
| I32Store16(ma)
| I64Store8(ma)
| I64Store16(ma)
| I64Store32(ma) => gen_valid_scan_scalar_memory_instr(ma, true)
BrOnNull(_) | BrOnNonNull(_) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
branch_ops: 1,
}
BrOnCast(_, _, _, _) | BrOnCastFail(_, _, _, _) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
has_basic_ref_instructions: true,
branch_ops: 1,
}
Block(bt, body) | Loop(bt, body) => {
let (has_ref, has_v128) = gen_valid_scan_block_type(bt)
let body_facts = gen_valid_scan_expr(body)
GenValidInstrFacts::{
..body_facts,
uses_ref_types: body_facts.uses_ref_types || has_ref,
uses_v128: body_facts.uses_v128 || has_v128,
has_payload_control_flow: body_facts.has_payload_control_flow ||
(
gen_valid_block_type_can_produce_values(bt) &&
gen_valid_expr_has_top_level_branch(body)
),
has_multivalue_control_flow: body_facts.has_multivalue_control_flow,
control_nodes: body_facts.control_nodes + 1,
}
}
If(bt, then_body, else_body) => {
let (has_ref, has_v128) = gen_valid_scan_block_type(bt)
let mut facts = GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: has_ref,
uses_v128: has_v128,
has_payload_control_flow: false,
has_multivalue_control_flow: false,
control_nodes: 1,
branch_ops: 1,
}
facts = gen_valid_merge_instr_facts(
facts,
gen_valid_scan_expr(Expr::new(then_body)),
)
match else_body {
Some(branch) =>
facts = gen_valid_merge_instr_facts(
facts,
gen_valid_scan_expr(Expr::new(branch)),
)
None => ()
}
let else_has_top_level_branch = match else_body {
Some(body) => gen_valid_instr_array_has_top_level_branch(body)
None => false
}
if gen_valid_block_type_can_produce_values(bt) &&
(
gen_valid_instr_array_has_top_level_branch(then_body) ||
else_has_top_level_branch
) {
facts = GenValidInstrFacts::{ ..facts, has_payload_control_flow: true, }
}
facts
}
Try(bt, body, catches, _) => {
let (has_ref, has_v128) = gen_valid_scan_block_type(bt)
let mut facts = gen_valid_scan_expr(body)
for catch_ in catches {
let handler = match catch_ {
@lib.LegacyCatch(_, handler) | @lib.LegacyCatchAll(handler) => handler
}
facts = gen_valid_merge_instr_facts(facts, gen_valid_scan_expr(handler))
}
GenValidInstrFacts::{
..facts,
uses_ref_types: facts.uses_ref_types || has_ref,
uses_v128: facts.uses_v128 || has_v128,
control_nodes: facts.control_nodes + 1,
branch_ops: facts.branch_ops + catches.length(),
}
}
TryTable(bt, catches, body) => {
let (has_ref, has_v128) = gen_valid_scan_block_type(bt)
let body_facts = gen_valid_scan_expr(body)
GenValidInstrFacts::{
..body_facts,
uses_ref_types: body_facts.uses_ref_types || has_ref,
uses_v128: body_facts.uses_v128 || has_v128,
has_payload_control_flow: body_facts.has_payload_control_flow ||
(
gen_valid_block_type_can_produce_values(bt) &&
gen_valid_expr_has_top_level_branch(body)
),
has_multivalue_control_flow: body_facts.has_multivalue_control_flow,
has_exception_try_table_matrix: body_facts.has_exception_try_table_matrix ||
gen_valid_try_table_has_exception_matrix(catches),
control_nodes: body_facts.control_nodes + 1,
branch_ops: body_facts.branch_ops + 1,
}
}
Select(Some(types)) => {
let mut uses_ref_types = false
let mut uses_v128 = false
for vt in types {
let (has_ref, has_v128) = gen_valid_scan_val_type(vt)
uses_ref_types = uses_ref_types || has_ref
uses_v128 = uses_v128 || has_v128
}
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types,
uses_v128,
has_typed_select: true,
}
}
RefNull(_) | RefIsNull | RefTest(_, _, _) | RefCast(_, _, _) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
has_basic_ref_instructions: gen_valid_instr_is_basic_ref_instruction(
instr,
),
}
RefI31 | I31GetS | I31GetU | AnyConvertExtern | ExternConvertAny =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
has_i31_extern_conversions: true,
}
StringConst(_)
| StringNewUtf8Array
| StringNewWtf16Array
| StringEncodeUtf8Array
| StringEncodeWtf16Array
| StringNewLossyUtf8Array
| StringNewWtf8Array
| StringEncodeLossyUtf8Array
| StringEncodeWtf8Array =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
has_string_ops: true,
}
RefFunc(_)
| ThrowRef
| RefGetDesc(_)
| RefTestDesc(_, _)
| RefCastDescEq(_, _, _) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
uses_ref_types: true,
}
Throw(_) =>
GenValidInstrFacts::{ ..GenValidInstrFacts::empty(), branch_ops: 1, }
Unreachable =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_standalone_unreachable: true,
}
LocalTee(_) =>
GenValidInstrFacts::{
..GenValidInstrFacts::empty(),
has_local_tee: true,
}
_ => GenValidInstrFacts::empty()
}
}
///|
fn gen_valid_module_typeidx_has_multiple_results(
mod : Module,
wanted : TypeIdx,
) -> Bool {
match mod.type_sec {
Some(TypeSec(rec_types)) => {
let mut cursor = 0U
for rec_type in rec_types {
match rec_type {
SingleRecType(sub_type) => {
match sub_type {
CompTypeSubType(_, FuncCompType(_, results)) if TypeIdx::new(
cursor,
) ==
wanted => return results.length() > 1
_ => ()
}
cursor += 1
}
GroupRecType(group) =>
for sub_type in group {
match sub_type {
CompTypeSubType(_, FuncCompType(_, results)) if TypeIdx::new(
cursor,
) ==
wanted => return results.length() > 1
_ => ()
}
cursor += 1
}
}
}
false
}
None => false
}
}
///|
fn gen_valid_expr_has_multivalue_control_flow(
mod : Module,
expr : Expr,
) -> Bool {
let Expr(instrs) = expr
for instr in instrs {
match instr {
Block(TypeIdxBlockType(type_idx), body)
| Loop(TypeIdxBlockType(type_idx), body)
| TryTable(TypeIdxBlockType(type_idx), _, body) => {
if gen_valid_module_typeidx_has_multiple_results(mod, type_idx) {
return true
}
if gen_valid_expr_has_multivalue_control_flow(mod, body) {
return true
}
}
Block(_, body) | Loop(_, body) | TryTable(_, _, body) =>
if gen_valid_expr_has_multivalue_control_flow(mod, body) {
return true
}
If(TypeIdxBlockType(type_idx), then_body, else_body) => {
if gen_valid_module_typeidx_has_multiple_results(mod, type_idx) {
return true
}
if gen_valid_expr_has_multivalue_control_flow(mod, Expr::new(then_body)) {
return true
}
match else_body {
Some(body) if gen_valid_expr_has_multivalue_control_flow(
mod,
Expr::new(body),
) => return true
_ => ()
}
}
If(_, then_body, else_body) => {
if gen_valid_expr_has_multivalue_control_flow(mod, Expr::new(then_body)) {
return true
}
match else_body {
Some(body) if gen_valid_expr_has_multivalue_control_flow(
mod,
Expr::new(body),
) => return true
_ => ()
}
}
_ => ()
}
}
false
}
///|
fn gen_valid_template_signature_push(
seen : Array[String],
label : String,
) -> Unit {
if label.length() > 0 {
seen.push(label)
}
}
///|
fn gen_valid_instr_template_signature_label(instr : Instruction) -> String {
if gen_valid_instr_is_expanded_scalar_numeric(instr) {
return "numeric"
}
if gen_valid_instr_is_gc_constructor(instr) ||
gen_valid_instr_is_gc_accessor(instr) {
return "gc"
}
if gen_valid_instr_is_simd_phase1(instr) {
return "simd1"
}
if gen_valid_instr_is_simd_phase2(instr) {
return "simd2"
}
if gen_valid_instr_is_simd_phase3(instr) {
return "simd3"
}
if gen_valid_instr_is_atomic(instr) {
return "atomic"
}
match instr {
Block(_, _) => "block"
Loop(_, _) => "loop"
If(_, _, _) => "if"
TryTable(_, _, _) => "try_table"
Br(_) | BrIf(_) | BrTable(_, _) => "branch"
Call(_) => "direct_call"
CallIndirect(_, _) => "call_indirect"
CallRef(_) => "call_ref"
ReturnCall(_) | ReturnCallIndirect(_, _) | ReturnCallRef(_) => "tail_call"
RefI31 | I31GetS | I31GetU | AnyConvertExtern | ExternConvertAny => "i31"
RefNull(_)
| RefIsNull
| RefFunc(_)
| RefTest(_, _, _)
| RefCast(_, _, _)
| BrOnCast(_, _, _, _)
| BrOnCastFail(_, _, _, _) => "ref"
MemorySize(_)
| MemoryGrow(_)
| MemoryInit(_, _)
| DataDrop(_)
| MemoryCopy(_, _)
| MemoryFill(_)
| I32Load(_)
| I64Load(_)
| F32Load(_)
| F64Load(_)
| I32Store(_)
| I64Store(_)
| F32Store(_)
| F64Store(_)
| I32Load8S(_)
| I32Load8U(_)
| I32Load16S(_)
| I32Load16U(_)
| I64Load8S(_)
| I64Load8U(_)
| I64Load16S(_)
| I64Load16U(_)
| I64Load32S(_)
| I64Load32U(_)
| I32Store8(_)
| I32Store16(_)
| I64Store8(_)
| I64Store16(_)
| I64Store32(_) => "memory"
TableSize(_)
| TableGet(_)
| TableSet(_)
| TableGrow(_)
| TableFill(_)
| TableCopy(_, _)
| TableInit(_, _)
| ElemDrop(_) => "table"
GlobalGet(_) | GlobalSet(_) => "global"
_ => ""
}
}
///|
fn gen_valid_collect_template_signature_instr(
seen : Array[String],
instr : Instruction,
) -> Unit {
gen_valid_template_signature_push(
seen,
gen_valid_instr_template_signature_label(instr),
)
match instr {
Block(_, body) | Loop(_, body) | TryTable(_, _, body) =>
gen_valid_collect_template_signature_expr(seen, body)
If(_, then_body, else_body) => {
gen_valid_collect_template_signature_instrs(seen, then_body)
match else_body {
Some(body) => gen_valid_collect_template_signature_instrs(seen, body)
None => ()
}
}
_ => ()
}
}
///|
fn gen_valid_collect_template_signature_instrs(
seen : Array[String],
instrs : Array[Instruction],
) -> Unit {
for instr in instrs {
gen_valid_collect_template_signature_instr(seen, instr)
}
}
///|
fn gen_valid_collect_template_signature_expr(
seen : Array[String],
expr : Expr,
) -> Unit {
let Expr(instrs) = expr
gen_valid_collect_template_signature_instrs(seen, instrs)
}
///|
fn gen_valid_join_template_signature(seen : Array[String]) -> String {
let out = StringBuilder::new()
let mut first = true
for label in seen {
if first {
first = false
} else {
out.write_string("|")
}
out.write_string(label)
}
out.to_string()
}
///|
pub fn gen_valid_coverage_template_signature(mod : Module) -> String {
let seen : Array[String] = []
match mod.code_sec {
Some(CodeSec(funcs)) =>
for func in funcs {
let Func(_, expr) = func
gen_valid_collect_template_signature_expr(seen, expr)
}
None => ()
}
gen_valid_join_template_signature(seen)
}
///|
fn gen_valid_local_idx_is_high(idx : LocalIdx) -> Bool {
let LocalIdx(raw) = idx
raw >= 16U
}
///|
fn gen_valid_expr_has_high_local_access(expr : Expr) -> Bool {
let Expr(instrs) = expr
for instr in instrs {
match instr {
LocalGet(idx) | LocalSet(idx) | LocalTee(idx) =>
if gen_valid_local_idx_is_high(idx) {
return true
}
Block(_, body) | Loop(_, body) | TryTable(_, _, body) =>
if gen_valid_expr_has_high_local_access(body) {
return true
}
If(_, then_body, else_body) => {
if gen_valid_expr_has_high_local_access(Expr::new(then_body)) {
return true
}
match else_body {
Some(body) if gen_valid_expr_has_high_local_access(Expr::new(body)) =>
return true
_ => ()
}
}
_ => ()
}
}
false
}
///|
fn gen_valid_expr_local_has_read(expr : Expr, wanted : LocalIdx) -> Bool {
let Expr(instrs) = expr
for instr in instrs {
match instr {
LocalGet(idx) | LocalTee(idx) if idx == wanted => return true
Block(_, body) | Loop(_, body) | TryTable(_, _, body) =>
if gen_valid_expr_local_has_read(body, wanted) {
return true
}
If(_, then_body, else_body) => {
if gen_valid_expr_local_has_read(Expr::new(then_body), wanted) {
return true
}
match else_body {
Some(body) if gen_valid_expr_local_has_read(Expr::new(body), wanted) =>
return true
_ => ()
}
}
_ => ()
}
}
false
}
///|
fn gen_valid_expr_local_has_write(expr : Expr, wanted : LocalIdx) -> Bool {
let Expr(instrs) = expr
for instr in instrs {
match instr {
LocalSet(idx) | LocalTee(idx) if idx == wanted => return true
Block(_, body) | Loop(_, body) | TryTable(_, _, body) =>
if gen_valid_expr_local_has_write(body, wanted) {
return true
}
If(_, then_body, else_body) => {
if gen_valid_expr_local_has_write(Expr::new(then_body), wanted) {
return true
}
match else_body {
Some(body) if gen_valid_expr_local_has_write(Expr::new(body), wanted) =>
return true
_ => ()
}
}
_ => ()
}
}
false
}
///|
fn gen_valid_module_typeidx_arities(
mod : Module,
wanted : TypeIdx,
) -> (Int32, Int32)? {
match mod.type_sec {
Some(TypeSec(rec_types)) => {
let mut cursor = 0U
for rec_type in rec_types {
match rec_type {
SingleRecType(sub_type) => {
match sub_type {
SubType(_, _, _, FuncCompType(params, results))
| CompTypeSubType(_, FuncCompType(params, results)) if TypeIdx::new(
cursor,
) ==
wanted => return Some((params.length(), results.length()))
_ => ()
}
cursor += 1
}
GroupRecType(group) =>
for sub_type in group {
match sub_type {
SubType(_, _, _, FuncCompType(params, results))
| CompTypeSubType(_, FuncCompType(params, results)) if TypeIdx::new(
cursor,
) ==
wanted => return Some((params.length(), results.length()))
_ => ()
}
cursor += 1
}
}
}
None
}
None => None
}
}
///|
fn gen_valid_module_typeidx_result_count(
mod : Module,
wanted : TypeIdx,
) -> Int32 {
match gen_valid_module_typeidx_arities(mod, wanted) {
Some((_, results)) => results
None => 0
}
}
///|
fn gen_valid_module_typeidx_param_count(
mod : Module,
wanted : TypeIdx,
) -> Int32 {
match mod.type_sec {
Some(TypeSec(rec_types)) => {
let mut cursor = 0U
for rec_type in rec_types {
match rec_type {
SingleRecType(sub_type) => {
match sub_type {
SubType(_, _, _, FuncCompType(params, _))
| CompTypeSubType(_, FuncCompType(params, _)) if TypeIdx::new(
cursor,
) ==
wanted => return params.length()
_ => ()
}
cursor += 1
}
GroupRecType(group) =>
for sub_type in group {
match sub_type {
SubType(_, _, _, FuncCompType(params, _))
| CompTypeSubType(_, FuncCompType(params, _)) if TypeIdx::new(
cursor,
) ==
wanted => return params.length()
_ => ()
}
cursor += 1
}
}
}
0
}
None => 0
}
}
///|
fn gen_valid_func_local_layout_facts(
param_count : Int32,
locals : Locals,
expr : Expr,
) -> (Bool, Bool) {
let mut has_unused = false
let mut has_write_only = false
let mut decl_cursor = 0
for _local_vt in locals.iter() {
let idx = LocalIdx::new((param_count + decl_cursor).reinterpret_as_uint())
let has_read = gen_valid_expr_local_has_read(expr, idx)
let has_write = gen_valid_expr_local_has_write(expr, idx)
if !has_read && !has_write {
has_unused = true
}
if has_write && !has_read {
has_write_only = true
}
decl_cursor += 1
}
(has_unused, has_write_only)
}
///|
pub fn gen_valid_feature_facts(
mod : Module,
mode : GenValidMode,
) -> GenValidFeatureFacts {
let proposal_floor_facts = gen_valid_proposal_floor_facts(mod)
let mut has_imports = false
let mut has_func_exports = false
let mut has_table_exports = false
let mut has_mem_exports = false
let mut has_global_exports = false
let mut has_tag_exports = false
let mut has_tables = false
let mut has_mems = false
let mut has_globals = false
let mut has_tags = false
let mut has_elems = false
let mut has_datas = false
let has_start = mod.start_sec is Some(_)
let has_data_count = mod.data_cnt_sec is Some(_)
let mut uses_ref_types = false
let mut uses_v128 = false
let mut has_call = false
let mut has_call_indirect = false
let mut has_numeric_full_ops = false
let mut has_br_table = false
let mut has_payload_control_flow = false
let mut has_multivalue_control_flow = false
let mut has_standalone_unreachable = false
let mut has_local_tee = false
let mut has_typed_select = false
let mut has_tail_calls = false
let mut has_grouped_local_decls = false
let mut has_mixed_local_decl_types = false
let mut has_high_local_indices = false
let mut has_unused_locals = false
let mut has_write_only_locals = false
let mut has_zero_local_funcs = false
let mut has_multi_param_result_arities = false
let mut has_empty_body_funcs = false
let mut has_unreachable_result_bodies = false
let mut has_local_name_entries = false
let mut has_scalar_memory_widths = false
let mut has_nonzero_memarg = false
let mut has_memory_limit_variants = false
let mut has_table_limit_variants = false
let mut has_const_expr_variants = false
let mut has_basic_ref_instructions = false
let mut has_i31_extern_conversions = false
let mut has_simd_phase1 = false
let mut has_simd_phase2 = false
let mut has_simd_phase3 = false
let mut has_atomics = false
let mut has_gc_constructors = false
let mut has_gc_accessors = false
let mut has_string_ops = false
let mut has_exception_try_table_matrix = false
let mut has_subtyping_topology = false
let mut has_rich_gc_field_plans = false
let mut has_import_export_topology = false
let mut has_element_segment_range = false
let mut has_data_segment_range = false
let mut has_name_custom_sections = false
let mut has_shared_memories = false
let mut exact_opcode_counts = GenValidExactOpcodeCounts::empty()
let mut control_nodes = 0
let mut branch_ops = 0
let mut ssa_facts = GenValidSsaFuncFacts::empty()
for custom in mod.custom_secs {
let @lib.CustomSec(name, _) = custom
if name != Name::new("name") {
has_name_custom_sections = true
}
}
match mod.name_sec {
Some(name_sec) => {
has_name_custom_sections = true
match name_sec.local_names {
Some(IndirectNameMap(entries)) if !entries.is_empty() =>
has_local_name_entries = true
_ => ()
}
}
None => ()
}
match mod.type_sec {
Some(TypeSec(rec_types)) =>
for rec_type in rec_types {
let (has_ref, has_v128_fact) = gen_valid_scan_rec_type(rec_type)
uses_ref_types = uses_ref_types || has_ref
uses_v128 = uses_v128 || has_v128_fact
has_subtyping_topology = has_subtyping_topology ||
gen_valid_scan_rec_type_topology(rec_type)
has_rich_gc_field_plans = has_rich_gc_field_plans ||
gen_valid_scan_rec_type_rich_gc_field_plan(rec_type)
}
None => ()
}
let import_modules : Array[Name] = []
let import_names : Array[Name] = []
let mut imported_func_count = 0
let mut imported_table_count = 0
let mut imported_mem_count = 0
let mut imported_global_count = 0
let mut imported_tag_count = 0
match mod.import_sec {
Some(ImportSec(imports)) =>
if !imports.is_empty() {
has_imports = true
for imp in imports {
let Import(module_name, import_name, extern_type) = imp
let mut saw_module = false
for existing in import_modules {
if existing == module_name {
saw_module = true
}
}
if !saw_module {
import_modules.push(module_name)
}
import_names.push(import_name)
match extern_type {
FuncExternType(_) => imported_func_count += 1
TableExternType(table_type) => {
imported_table_count += 1
has_tables = true
let TableType(ref_type, _) = table_type
uses_ref_types = uses_ref_types || true
uses_v128 = uses_v128 || false
has_table_limit_variants = has_table_limit_variants ||
gen_valid_table_type_has_limit_variant(table_type, None)
ignore(ref_type)
}
MemExternType(mt) => {
imported_mem_count += 1
has_mems = true
has_memory_limit_variants = has_memory_limit_variants ||
gen_valid_mem_type_has_limit_variant(mt)
has_shared_memories = has_shared_memories ||
gen_valid_mem_type_is_shared(mt)
}
GlobalExternType(global_type) => {
imported_global_count += 1
has_globals = true
let GlobalType(vt, _) = global_type
let (has_ref, has_v128_fact) = gen_valid_scan_val_type(vt)
uses_ref_types = uses_ref_types || has_ref
uses_v128 = uses_v128 || has_v128_fact
}
TagExternType(_) => {
imported_tag_count += 1
has_tags = true
}
}
}
}
None => ()
}
match mod.table_sec {
Some(TableSec(tables)) if !tables.is_empty() => {
has_tables = true
uses_ref_types = true
for table in tables {
let Table(table_type, init_opt) = table
has_table_limit_variants = has_table_limit_variants ||
gen_valid_table_type_has_limit_variant(table_type, init_opt)
match init_opt {
Some(init) => {
has_const_expr_variants = has_const_expr_variants ||
gen_valid_const_expr_has_variant(init)
let init_facts = gen_valid_scan_expr(init)
uses_ref_types = uses_ref_types || init_facts.uses_ref_types
uses_v128 = uses_v128 || init_facts.uses_v128
has_call = has_call || init_facts.has_call
has_call_indirect = has_call_indirect ||
init_facts.has_call_indirect
has_numeric_full_ops = has_numeric_full_ops ||
init_facts.has_numeric_full_ops
has_br_table = has_br_table || init_facts.has_br_table
has_standalone_unreachable = has_standalone_unreachable ||
init_facts.has_standalone_unreachable
has_local_tee = has_local_tee || init_facts.has_local_tee
has_typed_select = has_typed_select || init_facts.has_typed_select
has_tail_calls = has_tail_calls || init_facts.has_tail_calls
has_scalar_memory_widths = has_scalar_memory_widths ||
init_facts.has_scalar_memory_widths
has_nonzero_memarg = has_nonzero_memarg ||
init_facts.has_nonzero_memarg
has_basic_ref_instructions = has_basic_ref_instructions ||
init_facts.has_basic_ref_instructions
has_i31_extern_conversions = has_i31_extern_conversions ||
init_facts.has_i31_extern_conversions
has_simd_phase1 = has_simd_phase1 || init_facts.has_simd_phase1
has_simd_phase2 = has_simd_phase2 || init_facts.has_simd_phase2
has_simd_phase3 = has_simd_phase3 || init_facts.has_simd_phase3
has_atomics = has_atomics || init_facts.has_atomics
has_gc_constructors = has_gc_constructors ||
init_facts.has_gc_constructors
has_gc_accessors = has_gc_accessors || init_facts.has_gc_accessors
has_string_ops = has_string_ops || init_facts.has_string_ops
has_exception_try_table_matrix = has_exception_try_table_matrix ||
init_facts.has_exception_try_table_matrix
exact_opcode_counts = exact_opcode_counts.add(
init_facts.exact_opcode_counts,
)
control_nodes += init_facts.control_nodes
branch_ops += init_facts.branch_ops
}
None => ()
}
}
}
_ => ()
}
match mod.mem_sec {
Some(MemSec(mems)) if !mems.is_empty() => {
has_mems = true
for mt in mems {
has_memory_limit_variants = has_memory_limit_variants ||
gen_valid_mem_type_has_limit_variant(mt)
has_shared_memories = has_shared_memories ||
gen_valid_mem_type_is_shared(mt)
}
}
_ => ()
}
match mod.global_sec {
Some(GlobalSec(globals)) =>
if !globals.is_empty() {
has_globals = true
for global in globals {
let Global(global_type, expr) = global
let GlobalType(vt, _) = global_type
let (has_ref, has_v128_fact) = gen_valid_scan_val_type(vt)
has_const_expr_variants = has_const_expr_variants ||
gen_valid_const_expr_has_variant(expr)
let expr_facts = gen_valid_scan_expr(expr)
uses_ref_types = uses_ref_types ||
has_ref ||
expr_facts.uses_ref_types
uses_v128 = uses_v128 || has_v128_fact || expr_facts.uses_v128
has_call = has_call || expr_facts.has_call
has_call_indirect = has_call_indirect || expr_facts.has_call_indirect
has_numeric_full_ops = has_numeric_full_ops ||
expr_facts.has_numeric_full_ops
has_br_table = has_br_table || expr_facts.has_br_table
has_standalone_unreachable = has_standalone_unreachable ||
expr_facts.has_standalone_unreachable
has_local_tee = has_local_tee || expr_facts.has_local_tee
has_typed_select = has_typed_select || expr_facts.has_typed_select
has_tail_calls = has_tail_calls || expr_facts.has_tail_calls
has_scalar_memory_widths = has_scalar_memory_widths ||
expr_facts.has_scalar_memory_widths
has_nonzero_memarg = has_nonzero_memarg ||
expr_facts.has_nonzero_memarg
has_basic_ref_instructions = has_basic_ref_instructions ||
expr_facts.has_basic_ref_instructions
has_i31_extern_conversions = has_i31_extern_conversions ||
expr_facts.has_i31_extern_conversions
has_simd_phase1 = has_simd_phase1 || expr_facts.has_simd_phase1
has_simd_phase2 = has_simd_phase2 || expr_facts.has_simd_phase2
has_simd_phase3 = has_simd_phase3 || expr_facts.has_simd_phase3
has_atomics = has_atomics || expr_facts.has_atomics
has_gc_constructors = has_gc_constructors ||
expr_facts.has_gc_constructors
has_gc_accessors = has_gc_accessors || expr_facts.has_gc_accessors
has_string_ops = has_string_ops || expr_facts.has_string_ops
has_exception_try_table_matrix = has_exception_try_table_matrix ||
expr_facts.has_exception_try_table_matrix
exact_opcode_counts = exact_opcode_counts.add(
expr_facts.exact_opcode_counts,
)
control_nodes += expr_facts.control_nodes
branch_ops += expr_facts.branch_ops
}
}
None => ()
}
match mod.tag_sec {
Some(TagSec(tags)) if !tags.is_empty() => has_tags = true
_ => ()
}
match mod.export_sec {
Some(ExportSec(exports)) => {
let export_idxs : Array[ExternIdx] = []
for export_ in exports {
let Export(export_name, idx) = export_
for import_name in import_names {
if import_name == export_name {
has_import_export_topology = true
}
}
for prior_idx in export_idxs {
if prior_idx == idx {
has_import_export_topology = true
}
}
export_idxs.push(idx)
match idx {
FuncExternIdx(FuncIdx(func_idx)) => {
has_func_exports = true
has_import_export_topology = has_import_export_topology ||
func_idx.reinterpret_as_int() < imported_func_count
}
TableExternIdx(TableIdx(table_idx)) => {
has_table_exports = true
has_import_export_topology = has_import_export_topology ||
table_idx.reinterpret_as_int() < imported_table_count
}
MemExternIdx(MemIdx(mem_idx)) => {
has_mem_exports = true
has_import_export_topology = has_import_export_topology ||
mem_idx.reinterpret_as_int() < imported_mem_count
}
GlobalExternIdx(GlobalIdx(global_idx)) => {
has_global_exports = true
has_import_export_topology = has_import_export_topology ||
global_idx.reinterpret_as_int() < imported_global_count
}
TagExternIdx(TagIdx(tag_idx)) => {
has_tag_exports = true
has_import_export_topology = has_import_export_topology ||
tag_idx.reinterpret_as_int() < imported_tag_count
}
}
}
}
None => ()
}
has_import_export_topology = has_import_export_topology ||
(
has_imports &&
(
has_func_exports ||
has_table_exports ||
has_mem_exports ||
has_global_exports ||
has_tag_exports
)
) ||
import_modules.length() > 1 ||
(match mod.start_sec {
Some(StartSec(FuncIdx(func_idx))) =>
func_idx.reinterpret_as_int() < imported_func_count
None => false
})
match mod.elem_sec {
Some(ElemSec(elems)) =>
if !elems.is_empty() {
has_elems = true
uses_ref_types = true
for elem in elems {
let Elem(mode, kind) = elem
match mode {
Active(table_idx, expr) => {
let TableIdx(table_idx_u) = table_idx
has_element_segment_range = has_element_segment_range ||
table_idx_u.reinterpret_as_int() > 0
has_const_expr_variants = has_const_expr_variants ||
gen_valid_const_expr_has_variant(expr)
let facts = gen_valid_scan_expr(expr)
uses_ref_types = uses_ref_types || facts.uses_ref_types
uses_v128 = uses_v128 || facts.uses_v128
has_call = has_call || facts.has_call
has_call_indirect = has_call_indirect || facts.has_call_indirect
has_numeric_full_ops = has_numeric_full_ops ||
facts.has_numeric_full_ops
has_br_table = has_br_table || facts.has_br_table
has_standalone_unreachable = has_standalone_unreachable ||
facts.has_standalone_unreachable
has_local_tee = has_local_tee || facts.has_local_tee
has_typed_select = has_typed_select || facts.has_typed_select
has_tail_calls = has_tail_calls || facts.has_tail_calls
has_scalar_memory_widths = has_scalar_memory_widths ||
facts.has_scalar_memory_widths
has_nonzero_memarg = has_nonzero_memarg ||
facts.has_nonzero_memarg
has_basic_ref_instructions = has_basic_ref_instructions ||
facts.has_basic_ref_instructions
has_i31_extern_conversions = has_i31_extern_conversions ||
facts.has_i31_extern_conversions
has_simd_phase1 = has_simd_phase1 || facts.has_simd_phase1
has_simd_phase2 = has_simd_phase2 || facts.has_simd_phase2
has_simd_phase3 = has_simd_phase3 || facts.has_simd_phase3
has_atomics = has_atomics || facts.has_atomics
has_gc_constructors = has_gc_constructors ||
facts.has_gc_constructors
has_gc_accessors = has_gc_accessors || facts.has_gc_accessors
has_string_ops = has_string_ops || facts.has_string_ops
has_exception_try_table_matrix = has_exception_try_table_matrix ||
facts.has_exception_try_table_matrix
exact_opcode_counts = exact_opcode_counts.add(
facts.exact_opcode_counts,
)
control_nodes += facts.control_nodes
branch_ops += facts.branch_ops
}
_ => ()
}
match kind {
FuncsElemKind(funcs) =>
has_element_segment_range = has_element_segment_range ||
funcs.length() > 1
FuncExprsElemKind(exprs) => {
has_element_segment_range = has_element_segment_range ||
exprs.length() > 1
for expr in exprs {
has_const_expr_variants = has_const_expr_variants ||
gen_valid_const_expr_has_variant(expr)
let facts = gen_valid_scan_expr(expr)
uses_ref_types = uses_ref_types || facts.uses_ref_types
uses_v128 = uses_v128 || facts.uses_v128
has_call = has_call || facts.has_call
has_call_indirect = has_call_indirect || facts.has_call_indirect
has_numeric_full_ops = has_numeric_full_ops ||
facts.has_numeric_full_ops
has_br_table = has_br_table || facts.has_br_table
has_standalone_unreachable = has_standalone_unreachable ||
facts.has_standalone_unreachable
has_local_tee = has_local_tee || facts.has_local_tee
has_typed_select = has_typed_select || facts.has_typed_select
has_tail_calls = has_tail_calls || facts.has_tail_calls
has_scalar_memory_widths = has_scalar_memory_widths ||
facts.has_scalar_memory_widths
has_nonzero_memarg = has_nonzero_memarg ||
facts.has_nonzero_memarg
has_basic_ref_instructions = has_basic_ref_instructions ||
facts.has_basic_ref_instructions
has_i31_extern_conversions = has_i31_extern_conversions ||
facts.has_i31_extern_conversions
has_simd_phase1 = has_simd_phase1 || facts.has_simd_phase1
has_simd_phase2 = has_simd_phase2 || facts.has_simd_phase2
has_simd_phase3 = has_simd_phase3 || facts.has_simd_phase3
has_atomics = has_atomics || facts.has_atomics
has_gc_constructors = has_gc_constructors ||
facts.has_gc_constructors
has_gc_accessors = has_gc_accessors || facts.has_gc_accessors
has_string_ops = has_string_ops || facts.has_string_ops
has_exception_try_table_matrix = has_exception_try_table_matrix ||
facts.has_exception_try_table_matrix
exact_opcode_counts = exact_opcode_counts.add(
facts.exact_opcode_counts,
)
control_nodes += facts.control_nodes
branch_ops += facts.branch_ops
}
}
TypedExprsElemKind(rt, exprs) => {
has_element_segment_range = has_element_segment_range ||
exprs.length() > 1 ||
ValType::ref_type(rt) != ValType::funcref()
uses_ref_types = true
for expr in exprs {
has_const_expr_variants = has_const_expr_variants ||
gen_valid_const_expr_has_variant(expr)
let facts = gen_valid_scan_expr(expr)
uses_ref_types = uses_ref_types || facts.uses_ref_types
uses_v128 = uses_v128 || facts.uses_v128
has_call = has_call || facts.has_call
has_call_indirect = has_call_indirect || facts.has_call_indirect
has_numeric_full_ops = has_numeric_full_ops ||
facts.has_numeric_full_ops
has_br_table = has_br_table || facts.has_br_table
has_standalone_unreachable = has_standalone_unreachable ||
facts.has_standalone_unreachable
has_local_tee = has_local_tee || facts.has_local_tee
has_typed_select = has_typed_select || facts.has_typed_select
has_tail_calls = has_tail_calls || facts.has_tail_calls
has_scalar_memory_widths = has_scalar_memory_widths ||
facts.has_scalar_memory_widths
has_nonzero_memarg = has_nonzero_memarg ||
facts.has_nonzero_memarg
has_basic_ref_instructions = has_basic_ref_instructions ||
facts.has_basic_ref_instructions
has_i31_extern_conversions = has_i31_extern_conversions ||
facts.has_i31_extern_conversions
has_simd_phase1 = has_simd_phase1 || facts.has_simd_phase1
has_simd_phase2 = has_simd_phase2 || facts.has_simd_phase2
has_simd_phase3 = has_simd_phase3 || facts.has_simd_phase3
has_atomics = has_atomics || facts.has_atomics
has_gc_constructors = has_gc_constructors ||
facts.has_gc_constructors
has_gc_accessors = has_gc_accessors || facts.has_gc_accessors
has_string_ops = has_string_ops || facts.has_string_ops
has_exception_try_table_matrix = has_exception_try_table_matrix ||
facts.has_exception_try_table_matrix
exact_opcode_counts = exact_opcode_counts.add(
facts.exact_opcode_counts,
)
control_nodes += facts.control_nodes
branch_ops += facts.branch_ops
}
}
}
}
}
None => ()
}
match mod.data_sec {
Some(DataSec(datas)) =>
if !datas.is_empty() {
has_datas = true
let mut saw_zero_length_data = false
let mut saw_large_data = false
let mut saw_nonzero_memory_data = false
let mut saw_passive_data = false
let mut saw_active_data = false
for data in datas {
let Data(mode, payload) = data
saw_zero_length_data = saw_zero_length_data || payload.length() == 0
saw_large_data = saw_large_data || payload.length() > 16
match mode {
Active(mem_idx, expr) => {
saw_active_data = true
let MemIdx(mem_idx_u) = mem_idx
saw_nonzero_memory_data = saw_nonzero_memory_data ||
mem_idx_u.reinterpret_as_int() > 0
has_const_expr_variants = has_const_expr_variants ||
gen_valid_const_expr_has_variant(expr)
let facts = gen_valid_scan_expr(expr)
uses_ref_types = uses_ref_types || facts.uses_ref_types
uses_v128 = uses_v128 || facts.uses_v128
has_call = has_call || facts.has_call
has_call_indirect = has_call_indirect || facts.has_call_indirect
has_numeric_full_ops = has_numeric_full_ops ||
facts.has_numeric_full_ops
has_br_table = has_br_table || facts.has_br_table
has_standalone_unreachable = has_standalone_unreachable ||
facts.has_standalone_unreachable
has_local_tee = has_local_tee || facts.has_local_tee
has_typed_select = has_typed_select || facts.has_typed_select
has_tail_calls = has_tail_calls || facts.has_tail_calls
has_scalar_memory_widths = has_scalar_memory_widths ||
facts.has_scalar_memory_widths
has_nonzero_memarg = has_nonzero_memarg ||
facts.has_nonzero_memarg
has_basic_ref_instructions = has_basic_ref_instructions ||
facts.has_basic_ref_instructions
has_i31_extern_conversions = has_i31_extern_conversions ||
facts.has_i31_extern_conversions
has_simd_phase1 = has_simd_phase1 || facts.has_simd_phase1
has_simd_phase2 = has_simd_phase2 || facts.has_simd_phase2
has_simd_phase3 = has_simd_phase3 || facts.has_simd_phase3
has_atomics = has_atomics || facts.has_atomics
has_gc_constructors = has_gc_constructors ||
facts.has_gc_constructors
has_gc_accessors = has_gc_accessors || facts.has_gc_accessors
has_string_ops = has_string_ops || facts.has_string_ops
has_exception_try_table_matrix = has_exception_try_table_matrix ||
facts.has_exception_try_table_matrix
exact_opcode_counts = exact_opcode_counts.add(
facts.exact_opcode_counts,
)
control_nodes += facts.control_nodes
branch_ops += facts.branch_ops
}
Passive => saw_passive_data = true
}
}
has_data_segment_range = saw_large_data ||
saw_nonzero_memory_data ||
(saw_zero_length_data && saw_active_data && saw_passive_data)
}
None => ()
}
let defined_func_param_counts : Array[Int32] = []
let mod_defined_type_idxs : Array[TypeIdx] = []
match mod.func_sec {
Some(FuncSec(type_idxs)) =>
for type_idx in type_idxs {
mod_defined_type_idxs.push(type_idx)
defined_func_param_counts.push(
gen_valid_module_typeidx_param_count(mod, type_idx),
)
}
None => ()
}
match mod.code_sec {
Some(CodeSec(funcs)) =>
for func_idx = 0; func_idx < funcs.length(); func_idx = func_idx + 1 {
let func = funcs[func_idx]
let Func(locals, expr) = func
let Expr(body_instrs) = expr
if locals.is_empty() {
has_zero_local_funcs = true
}
if body_instrs.is_empty() {
has_empty_body_funcs = true
}
if body_instrs == [Instruction::unreachable_()] &&
func_idx < mod_defined_type_idxs.length() &&
gen_valid_module_typeidx_result_count(
mod,
mod_defined_type_idxs[func_idx],
) >
0 {
has_unreachable_result_bodies = true
}
if func_idx < mod_defined_type_idxs.length() {
let arity = gen_valid_module_typeidx_arities(
mod,
mod_defined_type_idxs[func_idx],
)
match arity {
Some((params, results)) if params > 1 && results > 1 =>
has_multi_param_result_arities = true
_ => ()
}
}
let local_runs = locals.runs()
if local_runs.length() > 1 {
has_mixed_local_decl_types = true
}
for run in local_runs {
if run.count() > 1U {
has_grouped_local_decls = true
}
}
for local_vt in locals.iter() {
let (has_ref, has_v128_fact) = gen_valid_scan_val_type(local_vt)
uses_ref_types = uses_ref_types || has_ref
uses_v128 = uses_v128 || has_v128_fact
}
let facts = gen_valid_scan_expr(expr)
has_high_local_indices = has_high_local_indices ||
gen_valid_expr_has_high_local_access(expr)
let param_count = if func_idx < defined_func_param_counts.length() {
defined_func_param_counts[func_idx]
} else {
0
}
let (func_has_unused, func_has_write_only) = gen_valid_func_local_layout_facts(
param_count, locals, expr,
)
ssa_facts = gen_valid_merge_ssa_func_facts(
ssa_facts,
gen_valid_scan_func_ssa_facts(param_count, locals, expr),
)
has_unused_locals = has_unused_locals || func_has_unused
has_write_only_locals = has_write_only_locals || func_has_write_only
uses_ref_types = uses_ref_types || facts.uses_ref_types
uses_v128 = uses_v128 || facts.uses_v128
has_call = has_call || facts.has_call
has_call_indirect = has_call_indirect || facts.has_call_indirect
has_numeric_full_ops = has_numeric_full_ops ||
facts.has_numeric_full_ops
has_br_table = has_br_table || facts.has_br_table
has_payload_control_flow = has_payload_control_flow ||
facts.has_payload_control_flow
has_multivalue_control_flow = has_multivalue_control_flow ||
facts.has_multivalue_control_flow ||
gen_valid_expr_has_multivalue_control_flow(mod, expr)
has_standalone_unreachable = has_standalone_unreachable ||
facts.has_standalone_unreachable
has_local_tee = has_local_tee || facts.has_local_tee
has_typed_select = has_typed_select || facts.has_typed_select
has_tail_calls = has_tail_calls || facts.has_tail_calls
has_scalar_memory_widths = has_scalar_memory_widths ||
facts.has_scalar_memory_widths
has_nonzero_memarg = has_nonzero_memarg || facts.has_nonzero_memarg
has_basic_ref_instructions = has_basic_ref_instructions ||
facts.has_basic_ref_instructions
has_i31_extern_conversions = has_i31_extern_conversions ||
facts.has_i31_extern_conversions
has_simd_phase1 = has_simd_phase1 || facts.has_simd_phase1
has_simd_phase2 = has_simd_phase2 || facts.has_simd_phase2
has_simd_phase3 = has_simd_phase3 || facts.has_simd_phase3
has_atomics = has_atomics || facts.has_atomics
has_gc_constructors = has_gc_constructors || facts.has_gc_constructors
has_gc_accessors = has_gc_accessors || facts.has_gc_accessors
has_string_ops = has_string_ops || facts.has_string_ops
has_exception_try_table_matrix = has_exception_try_table_matrix ||
facts.has_exception_try_table_matrix
exact_opcode_counts = exact_opcode_counts.add(facts.exact_opcode_counts)
control_nodes += facts.control_nodes
branch_ops += facts.branch_ops
}
None => ()
}
let has_gc_feature = has_gc_constructors ||
has_gc_accessors ||
has_subtyping_topology ||
has_rich_gc_field_plans
let has_any_export = has_func_exports ||
has_table_exports ||
has_mem_exports ||
has_global_exports ||
has_tag_exports
{
mode,
has_imports,
has_func_exports,
has_table_exports,
has_mem_exports,
has_global_exports,
has_tag_exports,
has_start,
lacks_start: !has_start,
has_tables,
has_mems,
has_globals,
has_tags,
has_elems,
has_datas,
has_data_count,
uses_ref_types,
uses_v128,
has_call,
has_call_indirect,
has_branch_heavy_control: branch_ops > 0 || control_nodes >= 2,
has_payload_control_flow,
has_multivalue_control_flow,
has_numeric_full_ops,
has_br_table,
has_standalone_unreachable,
has_local_tee,
has_typed_select,
has_tail_calls,
has_grouped_local_decls,
has_mixed_local_decl_types,
has_high_local_indices,
has_unused_locals,
has_write_only_locals,
has_zero_local_funcs,
has_multi_param_result_arities,
has_empty_body_funcs,
has_unreachable_result_bodies,
has_local_name_entries,
has_scalar_memory_widths,
has_nonzero_memarg,
has_memory_limit_variants,
has_table_limit_variants,
has_const_expr_variants,
has_basic_ref_instructions,
has_i31_extern_conversions,
has_simd_phase1,
has_simd_phase2,
has_simd_phase3,
has_descriptors: proposal_floor_facts.has_descriptors,
has_continuations: proposal_floor_facts.has_continuations,
has_waitqueues: proposal_floor_facts.has_waitqueues,
has_atomics,
has_array_memory: proposal_floor_facts.has_array_memory,
has_gc_constructors,
has_gc_accessors,
has_string_ops,
has_exception_try_table_matrix,
has_subtyping_topology,
has_rich_gc_field_plans,
has_import_export_topology,
has_element_segment_range,
has_data_segment_range,
has_name_custom_sections,
has_gc_exception_combo: has_gc_feature && has_exception_try_table_matrix,
has_gc_tail_call_combo: has_gc_feature && has_tail_calls,
has_shared_memory_atomics: has_shared_memories &&
proposal_floor_facts.has_linear_atomics,
has_imports_start_exports: has_imports && has_start && has_any_export,
has_semantic_effects: has_call ||
has_mems ||
has_globals ||
has_tables ||
has_tags,
has_import_event_channel: has_imports && (has_start || has_func_exports),
has_trap_frontier: has_standalone_unreachable ||
has_call_indirect ||
has_exception_try_table_matrix ||
has_scalar_memory_widths,
has_resource_observation: has_mems && has_tables && has_globals,
has_poisoned_dead_code: has_standalone_unreachable &&
(control_nodes >= 2 || branch_ops > 0),
has_ssa_straight_line_local_chain: ssa_facts.has_ssa_straight_line_local_chain,
has_ssa_already_ssa_local: ssa_facts.has_ssa_already_ssa_local,
has_ssa_multi_def_same_local: ssa_facts.has_ssa_multi_def_same_local,
has_ssa_param_entry_read: ssa_facts.has_ssa_param_entry_read,
has_ssa_local_tee_def_use: ssa_facts.has_ssa_local_tee_def_use,
has_ssa_tee_freshen_candidate: ssa_facts.has_ssa_tee_freshen_candidate,
has_ssa_tee_merge_feeding_candidate: ssa_facts.has_ssa_tee_merge_feeding_candidate,
has_ssa_tee_child_expression: ssa_facts.has_ssa_tee_child_expression,
has_ssa_param_write: ssa_facts.has_ssa_param_write,
has_ssa_dead_local_set: ssa_facts.has_ssa_dead_local_set,
has_ssa_dead_local_tee: ssa_facts.has_ssa_dead_local_tee,
has_ssa_if_join_phi_candidate: ssa_facts.has_ssa_if_join_phi_candidate,
has_ssa_loop_backedge_phi_candidate: ssa_facts.has_ssa_loop_backedge_phi_candidate,
has_ssa_br_table_phi_candidate: ssa_facts.has_ssa_br_table_phi_candidate,
has_ssa_parallel_copy_candidate: ssa_facts.has_ssa_parallel_copy_candidate,
has_ssa_parallel_copy_cycle_candidate: ssa_facts.has_ssa_parallel_copy_cycle_candidate,
has_ssa_default_local_merge: ssa_facts.has_ssa_default_local_merge,
has_ssa_one_arm_default_merge: ssa_facts.has_ssa_one_arm_default_merge,
has_ssa_one_arm_param_merge: ssa_facts.has_ssa_one_arm_param_merge,
has_ssa_both_arm_local_merge: ssa_facts.has_ssa_both_arm_local_merge,
has_ssa_loop_carried_local_merge: ssa_facts.has_ssa_loop_carried_local_merge,
has_ssa_mixed_fresh_canonical_writes: ssa_facts.has_ssa_mixed_fresh_canonical_writes,
has_ssa_unreachable_local_carrier: ssa_facts.has_ssa_unreachable_local_carrier,
has_ssa_dropped_increment_guard_shape: ssa_facts.has_ssa_dropped_increment_guard_shape,
has_ssa_dropped_increment_reversed_boundary: ssa_facts.has_ssa_dropped_increment_reversed_boundary,
has_ssa_exceptional_fail_closed_shape: ssa_facts.has_ssa_exceptional_fail_closed_shape,
has_ssa_typed_loop_param_fail_closed_shape: ssa_facts.has_ssa_typed_loop_param_fail_closed_shape,
has_ssa_nested_cfg_fail_closed_shape: ssa_facts.has_ssa_nested_cfg_fail_closed_shape,
has_ssa_nested_result_if_supported_shape: ssa_facts.has_ssa_nested_result_if_supported_shape,
has_ssa_nested_result_if_condition_write: ssa_facts.has_ssa_nested_result_if_condition_write,
has_ssa_nested_result_if_condition_value_block: ssa_facts.has_ssa_nested_result_if_condition_value_block,
has_ssa_nested_result_if_arm_value_block: ssa_facts.has_ssa_nested_result_if_arm_value_block,
has_ssa_nested_result_if_mixed_arm_value_block: ssa_facts.has_ssa_nested_result_if_mixed_arm_value_block,
has_ssa_nested_result_if_scalar_result: ssa_facts.has_ssa_nested_result_if_scalar_result,
has_ssa_structured_early_return_local: ssa_facts.has_ssa_structured_early_return_local,
has_ssa_block_branch_merge_copy: ssa_facts.has_ssa_block_branch_merge_copy,
has_ssa_block_br_if_merge_copy: ssa_facts.has_ssa_block_br_if_merge_copy,
has_ssa_structured_param_merge: ssa_facts.has_ssa_structured_param_merge,
has_ssa_branch_local_not_read_later: ssa_facts.has_ssa_branch_local_not_read_later,
has_ssa_default_local_read_after_branchy_control: ssa_facts.has_ssa_default_local_read_after_branchy_control,
has_ssa_dropped_unreachable_debris_before_hard_unreachable: ssa_facts.has_ssa_dropped_unreachable_debris_before_hard_unreachable,
has_ssa_canonical_body_local_next_read: ssa_facts.has_ssa_canonical_body_local_next_read,
has_ssa_immediate_block_exit_canonical_set_br: ssa_facts.has_ssa_immediate_block_exit_canonical_set_br,
has_ssa_enclosing_label_copy_before_exit: ssa_facts.has_ssa_enclosing_label_copy_before_exit,
has_ssa_branch_block_alias_copy: ssa_facts.has_ssa_branch_block_alias_copy,
has_ssa_nested_enclosing_label_copy: ssa_facts.has_ssa_nested_enclosing_label_copy,
has_ssa_parallel_branch_carrier_copy: ssa_facts.has_ssa_parallel_branch_carrier_copy,
has_ssa_tee_branch_carrier_copy: ssa_facts.has_ssa_tee_branch_carrier_copy,
has_ssa_void_br_table_canonical_copies: ssa_facts.has_ssa_void_br_table_canonical_copies,
has_ssa_branch_operand_local_boundary: ssa_facts.has_ssa_branch_operand_local_boundary,
has_ssa_nested_loop_target_boundary: ssa_facts.has_ssa_nested_loop_target_boundary,
has_ssa_large_structured_local_mix: ssa_facts.has_ssa_large_structured_local_mix,
exact_opcode_counts,
}
}