Merge pull request #1592 from alexcrichton/explicit-self

Include self-pointer in `Function` descriptions
This commit is contained in:
Alex Crichton
2019-06-11 17:11:58 -05:00
committed by GitHub
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 /// The string value here is the class that this should be a constructor
/// for. /// for.
constructor: Option<String>, constructor: Option<String>,
/// whether or not we're generating a method
method: bool,
} }
impl<'a, 'b> Js2Rust<'a, 'b> { impl<'a, 'b> Js2Rust<'a, 'b> {
@ -83,6 +86,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
ret_ty: String::new(), ret_ty: String::new(),
ret_expr: String::new(), ret_expr: String::new(),
constructor: None, constructor: None,
method: false,
} }
} }
@ -93,12 +97,19 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
function: &Function, function: &Function,
opt_arg_names: &Option<Vec<String>>, opt_arg_names: &Option<Vec<String>>,
) -> Result<&mut Self, Error> { ) -> 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 { let arg_names = match opt_arg_names {
Some(arg_names) => arg_names.iter().map(|s| Some(s.as_str())).collect(), 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()); assert_eq!(arg_names.len(), arguments.len());
for (arg, arg_name) in function.arguments.iter().zip(arg_names) { for (arg, arg_name) in arguments.iter().zip(arg_names) {
// Process the function argument and assert that the metadata about // Process the function argument and assert that the metadata about
// the number of arguments on the Rust side required is correct. // the number of arguments on the Rust side required is correct.
let before = self.rust_arguments.len(); 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 /// Flag this shim as a method call into Rust, so the first Rust argument
/// passed should be `this.ptr`. /// passed should be `this.ptr`.
pub fn method(&mut self, consumed: bool) -> &mut Self { pub fn method(&mut self, consumed: bool) -> &mut Self {
self.method = true;
if self.cx.config.debug { if self.cx.config.debug {
self.prelude( self.prelude(
"if (this.ptr === 0) { "if (this.ptr === 0) {

View File

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