mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-16 02:00:51 +00:00
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:
parent
535aa3193c
commit
afbd7d3ff8
@ -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) {
|
||||
|
@ -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,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user