MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / generate

Method generate

cranelift/fuzzgen/src/function_generator.rs:1944–1992  ·  view source on GitHub ↗

We generate a function in multiple stages: First we generate a random number of empty blocks Then we generate a random pool of variables to be used throughout the function We then visit each block and generate random instructions Because we generate all blocks and variables up front we already know everything that we need when generating instructions (i.e. jump targets / variables)

(mut self)

Source from the content-addressed store, hash-verified

1942 /// Because we generate all blocks and variables up front we already know everything that
1943 /// we need when generating instructions (i.e. jump targets / variables)
1944 pub fn generate(mut self) -> Result<Function> {
1945 let mut fn_builder_ctx = FunctionBuilderContext::new();
1946 let mut func = Function::with_name_signature(self.name.clone(), self.signature.clone());
1947
1948 let mut builder = FunctionBuilder::new(&mut func, &mut fn_builder_ctx);
1949
1950 // Build the function references before generating the block CFG since we store
1951 // function references in the CFG.
1952 self.generate_funcrefs(&mut builder)?;
1953 self.generate_blocks(&mut builder)?;
1954
1955 // Function preamble
1956 self.generate_stack_slots(&mut builder)?;
1957
1958 // Main instruction generation loop
1959 for (block, block_sig) in self.resources.blocks.clone().into_iter() {
1960 let is_block0 = block.as_u32() == 0;
1961 builder.switch_to_block(block);
1962
1963 if is_block0 {
1964 // The first block is special because we must create variables both for the
1965 // block signature and for the variable pool. Additionally, we must also define
1966 // initial values for all variables that are not the function signature.
1967 self.build_variable_pool(&mut builder)?;
1968
1969 // Stack slots have random bytes at the beginning of the function
1970 // initialize them to a constant value so that execution stays predictable.
1971 self.initialize_stack_slots(&mut builder)?;
1972 } else {
1973 // Define variables for the block params
1974 for (i, ty) in block_sig.iter().enumerate() {
1975 let var = self.get_variable_of_type(*ty)?;
1976 let block_param = builder.block_params(block)[i];
1977 builder.def_var(var, block_param);
1978 }
1979 }
1980
1981 // Generate block instructions
1982 self.generate_instructions(&mut builder)?;
1983
1984 // Insert a terminator to safely exit the block
1985 self.insert_terminator(&mut builder, block)?;
1986 }
1987
1988 builder.seal_all_blocks();
1989 builder.finalize();
1990
1991 Ok(func)
1992 }
1993}

Callers 1

generate_funcMethod · 0.45

Calls 15

OkFunction · 0.85
generate_funcrefsMethod · 0.80
generate_blocksMethod · 0.80
generate_stack_slotsMethod · 0.80
switch_to_blockMethod · 0.80
build_variable_poolMethod · 0.80
get_variable_of_typeMethod · 0.80
generate_instructionsMethod · 0.80
insert_terminatorMethod · 0.80
newFunction · 0.50
cloneMethod · 0.45

Tested by

no test coverage detected