Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Derived Clone and Copy for DataKind. Added locals to LocalFunction. #230

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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