Skip to content

Commit

Permalink
Derived Clone and Copy for DataKind. Added locals to LocalFunction.
Browse files Browse the repository at this point in the history
  • Loading branch information
lbrande committed Apr 26, 2022
1 parent 9d6c9de commit 10e1abf
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 17 deletions.
3 changes: 2 additions & 1 deletion crates/tests/tests/custom_sections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ fn smoke_test_code_transform() {

let mut builder = walrus::FunctionBuilder::new(&mut module.types, &[], &[ValType::I32]);
builder.func_body().i32_const(1337);
let args = vec![];
let locals = vec![];
let f_id = builder.finish(locals, &mut module.funcs);
let f_id = builder.finish(args, locals, &mut module.funcs);

module.exports.add("f", f_id);

Expand Down
2 changes: 1 addition & 1 deletion examples/build-wasm-from-scratch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ fn main() -> walrus::Result<()> {
})
.local_get(res);

let factorial = factorial.finish(vec![n], &mut module.funcs);
let factorial = factorial.finish(vec![], vec![n], &mut module.funcs);

// Export the `factorial` function.
module.exports.add("factorial", factorial);
Expand Down
15 changes: 10 additions & 5 deletions src/function_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,22 @@ impl FunctionBuilder {
/// .i32_const(1234)
/// .drop();
///
/// let function_id = builder.finish(vec![], &mut module.funcs);
/// let function_id = builder.finish(vec![], vec![], &mut module.funcs);
/// # let _ = function_id;
/// ```
pub fn finish(self, args: Vec<LocalId>, funcs: &mut ModuleFunctions) -> FunctionId {
let func = LocalFunction::new(args, self);
pub fn finish(
self,
args: Vec<LocalId>,
locals: Vec<LocalId>,
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<LocalId>) -> LocalFunction {
LocalFunction::new(args, self)
pub fn local_func(self, args: Vec<LocalId>, locals: Vec<LocalId>) -> LocalFunction {
LocalFunction::new(args, locals, self)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/ir/traversals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ mod tests {
.i32_const(6)
.drop();

let func_id = builder.finish(vec![], &mut module.funcs);
let func_id = builder.finish(vec![], vec![], &mut module.funcs);
module.funcs.get_mut(func_id).kind.unwrap_local_mut()
}

Expand Down
4 changes: 2 additions & 2 deletions src/module/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions src/module/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ mod tests {
let mut module = Module::default();
let mut builder = FunctionBuilder::new(&mut module.types, &[], &[]);
builder.func_body().i32_const(1234).drop();
let id: FunctionId = builder.finish(vec![], &mut module.funcs);
let id: FunctionId = builder.finish(vec![], vec![], &mut module.funcs);
module.exports.add("dummy", id);

let actual: Option<&Export> = module.exports.get_exported_func(id);
Expand Down Expand Up @@ -352,11 +352,11 @@ mod tests {

let mut builder = FunctionBuilder::new(&mut module.types, &[], &[]);
builder.func_body().i32_const(1234).drop();
let fn_id0: FunctionId = builder.finish(vec![], &mut module.funcs);
let fn_id0: FunctionId = builder.finish(vec![], vec![], &mut module.funcs);

let mut builder = FunctionBuilder::new(&mut module.types, &[], &[]);
builder.func_body().i32_const(1234).drop();
let fn_id1: FunctionId = builder.finish(vec![], &mut module.funcs);
let fn_id1: FunctionId = builder.finish(vec![], vec![], &mut module.funcs);

assert_ne!(fn_id0, fn_id1);

Expand Down
17 changes: 15 additions & 2 deletions src/module/functions/local_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,26 @@ pub struct LocalFunction {

/// Arguments to this function, and the locals that they're assigned to.
pub args: Vec<LocalId>,

/// Locals of this function, excluding arguments.
pub locals: Vec<LocalId>,
//
// TODO: provenance: (InstrSeqId, usize) -> offset in code section of the
// original instruction. This will be necessary for preserving debug info.
}

impl LocalFunction {
/// Creates a new definition of a local function from its components.
pub(crate) fn new(args: Vec<LocalId>, builder: FunctionBuilder) -> LocalFunction {
LocalFunction { args, builder }
pub(crate) fn new(
args: Vec<LocalId>,
locals: Vec<LocalId>,
builder: FunctionBuilder,
) -> LocalFunction {
LocalFunction {
args,
locals,
builder,
}
}

/// Construct a new `LocalFunction`.
Expand All @@ -42,13 +53,15 @@ impl LocalFunction {
id: FunctionId,
ty: TypeId,
args: Vec<LocalId>,
locals: Vec<LocalId>,
mut body: wasmparser::BinaryReader<'_>,
on_instr_pos: Option<&(dyn Fn(&usize) -> InstrLocId + Sync + Send + 'static)>,
mut validator: FuncValidator<ValidatorResources>,
) -> Result<LocalFunction> {
let mut func = LocalFunction {
builder: FunctionBuilder::without_entry(ty),
args,
locals,
};

let result: Vec<_> = module.types.get(ty).results().iter().cloned().collect();
Expand Down
7 changes: 5 additions & 2 deletions src/module/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()?;
Expand All @@ -375,20 +376,21 @@ 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);
}
}
}

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(
Expand All @@ -397,6 +399,7 @@ impl Module {
id,
ty,
args,
locals,
body,
on_instr_pos,
validator,
Expand Down

0 comments on commit 10e1abf

Please sign in to comment.