diff --git a/src/function_builder.rs b/src/function_builder.rs index b708adad..76d4143c 100644 --- a/src/function_builder.rs +++ b/src/function_builder.rs @@ -150,14 +150,14 @@ impl FunctionBuilder { /// let function_id = builder.finish(vec![], &mut module.funcs); /// # let _ = function_id; /// ``` - pub fn finish(self, args: Vec, funcs: &mut ModuleFunctions) -> FunctionId { - let func = LocalFunction::new(args, self); + pub fn finish(self, args: Vec, locals: Vec, funcs: &mut ModuleFunctions) -> FunctionId { + let func = LocalFunction::new(args, locals, self); funcs.add_local(func) } /// Returns the [crate::LocalFunction] built by this builder. - pub fn local_func(self, args: Vec) -> LocalFunction { - LocalFunction::new(args, self) + pub fn local_func(self, args: Vec, locals: Vec) -> LocalFunction { + LocalFunction::new(args, locals, self) } } diff --git a/src/module/data.rs b/src/module/data.rs index 58acd1d6..943ca6c6 100644 --- a/src/module/data.rs +++ b/src/module/data.rs @@ -28,7 +28,7 @@ pub struct Data { } /// The kind of data segment: passive or active. -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub enum DataKind { /// An active data segment that is automatically initialized at some address /// in a static memory. @@ -41,7 +41,7 @@ pub enum DataKind { } /// The parts of a data segment that are only present in active data segments. -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct ActiveData { /// The memory that this active data segment will be automatically /// initialized in. diff --git a/src/module/functions/local_function/mod.rs b/src/module/functions/local_function/mod.rs index c4507c9d..08327d94 100644 --- a/src/module/functions/local_function/mod.rs +++ b/src/module/functions/local_function/mod.rs @@ -21,6 +21,9 @@ pub struct LocalFunction { /// Arguments to this function, and the locals that they're assigned to. pub args: Vec, + + /// Locals of this function, excluding arguments. + pub locals: Vec, // // TODO: provenance: (InstrSeqId, usize) -> offset in code section of the // original instruction. This will be necessary for preserving debug info. @@ -28,8 +31,8 @@ pub struct LocalFunction { impl LocalFunction { /// Creates a new definition of a local function from its components. - pub(crate) fn new(args: Vec, builder: FunctionBuilder) -> LocalFunction { - LocalFunction { args, builder } + pub(crate) fn new(args: Vec, locals: Vec, builder: FunctionBuilder) -> LocalFunction { + LocalFunction { args, locals, builder } } /// Construct a new `LocalFunction`. @@ -42,6 +45,7 @@ impl LocalFunction { id: FunctionId, ty: TypeId, args: Vec, + locals: Vec, mut body: wasmparser::BinaryReader<'_>, on_instr_pos: Option<&(dyn Fn(&usize) -> InstrLocId + Sync + Send + 'static)>, mut validator: FuncValidator, @@ -49,6 +53,7 @@ impl LocalFunction { let mut func = LocalFunction { builder: FunctionBuilder::without_entry(ty), args, + locals, }; let result: Vec<_> = module.types.get(ty).results().iter().cloned().collect(); diff --git a/src/module/functions/mod.rs b/src/module/functions/mod.rs index e782240b..c5cbfcba 100644 --- a/src/module/functions/mod.rs +++ b/src/module/functions/mod.rs @@ -366,6 +366,7 @@ impl Module { // Next up comes all the locals of the function. let mut reader = body.get_binary_reader(); + let mut locals = Vec::new(); for _ in 0..reader.read_var_u32()? { let pos = reader.original_position(); let count = reader.read_var_u32()?; @@ -375,6 +376,7 @@ impl Module { for _ in 0..count { let local_id = self.locals.add(ty); let idx = indices.push_local(id, local_id); + locals.push(local_id); if self.config.generate_synthetic_names_for_anonymous_items { let name = format!("l{}", idx); self.locals.get_mut(local_id).name = Some(name); @@ -382,13 +384,13 @@ impl Module { } } - bodies.push((id, reader, args, ty, validator)); + bodies.push((id, reader, args, locals, ty, validator)); } // Wasm modules can often have a lot of functions and this operation can // take some time, so parse all function bodies in parallel. let results = maybe_parallel!(bodies.(into_iter | into_par_iter)) - .map(|(id, body, args, ty, validator)| { + .map(|(id, body, args, locals, ty, validator)| { ( id, LocalFunction::parse( @@ -397,6 +399,7 @@ impl Module { id, ty, args, + locals, body, on_instr_pos, validator,