Include self-pointer in Function descriptions

Previously a `Function` didn't actually take into account the self
pointer and instead left it as an implicit argument. This instead
ensures that there's a `Descriptor::I32` type inside of a `Function`
description that we have to later skip, and this should not only make
the anyref pass correct for Rust exports but it should also make it more
accurate for future webidl transformations.
This commit is contained in:
Alex Crichton 2019-06-11 11:58:06 -07:00
parent 535aa3193c
commit afbd7d3ff8
2 changed files with 40 additions and 19 deletions

View File

@ -68,6 +68,9 @@ pub struct Js2Rust<'a, 'b: 'a> {
/// The string value here is the class that this should be a constructor
/// for.
constructor: Option<String>,
/// whether or not we're generating a method
method: bool,
}
impl<'a, 'b> Js2Rust<'a, 'b> {
@ -83,6 +86,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
ret_ty: String::new(),
ret_expr: String::new(),
constructor: None,
method: false,
}
}
@ -93,12 +97,19 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
function: &Function,
opt_arg_names: &Option<Vec<String>>,
) -> Result<&mut Self, Error> {
// Chop off the implicit i32 first argument if we're a method since it
// was already handled by `method` below.
let arguments = if self.method {
&function.arguments[1..]
} else {
&function.arguments[..]
};
let arg_names = match opt_arg_names {
Some(arg_names) => arg_names.iter().map(|s| Some(s.as_str())).collect(),
None => vec![None; function.arguments.len()],
None => vec![None; arguments.len()],
};
assert_eq!(arg_names.len(), function.arguments.len());
for (arg, arg_name) in function.arguments.iter().zip(arg_names) {
assert_eq!(arg_names.len(), arguments.len());
for (arg, arg_name) in arguments.iter().zip(arg_names) {
// Process the function argument and assert that the metadata about
// the number of arguments on the Rust side required is correct.
let before = self.rust_arguments.len();
@ -124,6 +135,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
/// Flag this shim as a method call into Rust, so the first Rust argument
/// passed should be `this.ptr`.
pub fn method(&mut self, consumed: bool) -> &mut Self {
self.method = true;
if self.cx.config.debug {
self.prelude(
"if (this.ptr === 0) {

View File

@ -580,7 +580,7 @@ impl<'a> Context<'a> {
Some(class) => struct_function_export_name(class, export.function.name),
None => export.function.name.to_string(),
};
let descriptor = match self.descriptors.remove(&wasm_name) {
let mut descriptor = match self.descriptors.remove(&wasm_name) {
None => return Ok(()),
Some(d) => d.unwrap_function(),
};
@ -595,23 +595,32 @@ impl<'a> Context<'a> {
match export.method_kind {
decode::MethodKind::Constructor => AuxExportKind::Constructor(class),
decode::MethodKind::Operation(op) => match op.kind {
decode::OperationKind::Getter(f) => AuxExportKind::Getter {
class,
field: f.to_string(),
},
decode::OperationKind::Setter(f) => AuxExportKind::Setter {
class,
field: f.to_string(),
},
decode::OperationKind::Getter(f) => {
descriptor.arguments.insert(0, Descriptor::I32);
AuxExportKind::Getter {
class,
field: f.to_string(),
}
}
decode::OperationKind::Setter(f) => {
descriptor.arguments.insert(0, Descriptor::I32);
AuxExportKind::Setter {
class,
field: f.to_string(),
}
}
_ if op.is_static => AuxExportKind::StaticFunction {
class,
name: export.function.name.to_string(),
},
_ => AuxExportKind::Method {
class,
name: export.function.name.to_string(),
consumed: export.consumed,
},
_ => {
descriptor.arguments.insert(0, Descriptor::I32);
AuxExportKind::Method {
class,
name: export.function.name.to_string(),
consumed: export.consumed,
}
}
},
}
}
@ -931,7 +940,7 @@ impl<'a> Context<'a> {
// Register a webidl transformation for the getter
let (getter_id, _) = self.function_exports[&getter];
let getter_descriptor = Function {
arguments: Vec::new(),
arguments: vec![Descriptor::I32],
shim_idx: 0,
ret: descriptor.clone(),
};
@ -956,7 +965,7 @@ impl<'a> Context<'a> {
let (setter_id, _) = self.function_exports[&setter];
let setter_descriptor = Function {
arguments: vec![descriptor],
arguments: vec![Descriptor::I32, descriptor],
shim_idx: 0,
ret: Descriptor::Unit,
};