Browse Source

Correctly count the number of wasm parameters. (#1337)

* Correctly count the number of wasm parameters.

Following up on #1329, this further replaces `num_normal_params` with a function
which calls `is_wasm_parameter` to correctly count the number of wasm
parameters a function has.

* Move is_wasm_parameter's implementation into the trait.
pull/1019/head
Dan Gohman 5 years ago
committed by GitHub
parent
commit
1d504ecf6d
  1. 10
      cranelift/codegen/src/ir/extfunc.rs
  2. 4
      cranelift/wasm/src/environ/dummy.rs
  3. 4
      cranelift/wasm/src/environ/spec.rs
  4. 2
      cranelift/wasm/src/func_translator.rs
  5. 16
      cranelift/wasm/src/state/func_state.rs

10
cranelift/codegen/src/ir/extfunc.rs

@ -88,16 +88,6 @@ impl Signature {
.count()
}
/// Count the number of normal parameters in a signature.
/// Exclude special-purpose parameters that represent runtime stuff and not WebAssembly
/// arguments.
pub fn num_normal_params(&self) -> usize {
self.params
.iter()
.filter(|arg| arg.purpose == ArgumentPurpose::Normal)
.count()
}
/// Does this signature take an struct return pointer parameter?
pub fn uses_struct_return_param(&self) -> bool {
self.uses_special_param(ArgumentPurpose::StructReturn)

4
cranelift/wasm/src/environ/dummy.rs

@ -201,10 +201,6 @@ impl<'dummy_environment> TargetEnvironment for DummyFuncEnvironment<'dummy_envir
}
impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environment> {
fn is_wasm_parameter(&self, func: &ir::Function, index: usize) -> bool {
func.signature.params[index].purpose == ir::ArgumentPurpose::Normal
}
fn return_mode(&self) -> ReturnMode {
self.return_mode
}

4
cranelift/wasm/src/environ/spec.rs

@ -140,7 +140,9 @@ pub trait TargetEnvironment {
pub trait FuncEnvironment: TargetEnvironment {
/// Is the given parameter of the given function a wasm-level parameter, as opposed to a hidden
/// parameter added for use by the implementation?
fn is_wasm_parameter(&self, func: &ir::Function, index: usize) -> bool;
fn is_wasm_parameter(&self, signature: &ir::Signature, index: usize) -> bool {
signature.params[index].purpose == ir::ArgumentPurpose::Normal
}
/// Should the code be structured to use a single `fallthrough_return` instruction at the end
/// of the function body, rather than `return` instructions as needed? This is used by VMs

2
cranelift/wasm/src/func_translator.rs

@ -135,7 +135,7 @@ fn declare_wasm_parameters<FE: FuncEnvironment + ?Sized>(
let param_type = builder.func.signature.params[i];
// There may be additional special-purpose parameters in addition to the normal WebAssembly
// signature parameters. For example, a `vmctx` pointer.
if environ.is_wasm_parameter(&builder.func, i) {
if environ.is_wasm_parameter(&builder.func.signature, i) {
// This is a normal WebAssembly signature parameter, so create a local for it.
let local = Variable::new(next_local);
builder.declare_var(local, param_type.value_type);

16
cranelift/wasm/src/state/func_state.rs

@ -474,7 +474,7 @@ impl FuncTranslationState {
Occupied(entry) => Ok(*entry.get()),
Vacant(entry) => {
let sig = environ.make_indirect_sig(func, index)?;
Ok(*entry.insert((sig, func.dfg.signatures[sig].num_normal_params())))
Ok(*entry.insert((sig, num_wasm_parameters(environ, &func.dfg.signatures[sig]))))
}
}
}
@ -495,8 +495,20 @@ impl FuncTranslationState {
Vacant(entry) => {
let fref = environ.make_direct_func(func, index)?;
let sig = func.dfg.ext_funcs[fref].signature;
Ok(*entry.insert((fref, func.dfg.signatures[sig].num_normal_params())))
Ok(*entry.insert((
fref,
num_wasm_parameters(environ, &func.dfg.signatures[sig]),
)))
}
}
}
}
fn num_wasm_parameters<FE: FuncEnvironment + ?Sized>(
environ: &FE,
signature: &ir::Signature,
) -> usize {
(0..signature.params.len())
.filter(|index| environ.is_wasm_parameter(signature, *index))
.count()
}

Loading…
Cancel
Save