Skip to content

Commit d5a9208

Browse files
authored
Merge pull request #1344 from c410-f3r/arg-names
Preserve argument names
2 parents e075d04 + 91ea972 commit d5a9208

File tree

10 files changed

+97
-14
lines changed

10 files changed

+97
-14
lines changed

crates/backend/src/encode.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,22 @@ fn shared_export<'a>(export: &'a ast::Export, intern: &'a Interner) -> Export<'a
165165
}
166166

167167
fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Function<'a> {
168-
Function { name: &func.name }
168+
let arg_names = func
169+
.arguments
170+
.iter()
171+
.enumerate()
172+
.map(|(idx, arg)| {
173+
if let syn::Pat::Ident(ref x) = arg.pat {
174+
x.ident.to_string()
175+
} else {
176+
format!("arg{}", idx)
177+
}
178+
})
179+
.collect::<Vec<_>>();
180+
Function {
181+
name: &func.name,
182+
arg_names,
183+
}
169184
}
170185

171186
fn shared_enum<'a>(e: &'a ast::Enum, intern: &'a Interner) -> Enum<'a> {
@@ -364,6 +379,12 @@ impl<'a> Encode for &'a str {
364379
}
365380
}
366381

382+
impl<'a> Encode for String {
383+
fn encode(&self, dst: &mut Encoder) {
384+
self.as_bytes().encode(dst);
385+
}
386+
}
387+
367388
impl<T: Encode> Encode for Vec<T> {
368389
fn encode(&self, dst: &mut Encoder) {
369390
self.len().encode(dst);

crates/cli-support/src/decode.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ impl<'src> Decode<'src> for &'src str {
4646
}
4747
}
4848

49+
impl<'src> Decode<'src> for String {
50+
fn decode(data: &mut &'src [u8]) -> String {
51+
let n = u32::decode(data);
52+
let (a, b) = data.split_at(n as usize);
53+
*data = b;
54+
String::from_utf8(a.to_vec()).unwrap()
55+
}
56+
}
57+
4958
impl<'src, T: Decode<'src>> Decode<'src> for Vec<T> {
5059
fn decode(data: &mut &'src [u8]) -> Self {
5160
let n = u32::decode(data);

crates/cli-support/src/js/closures.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ impl ClosureDescriptors {
193193
builder.rust_argument("this.a").rust_argument("b");
194194
}
195195
builder.finally("if (this.cnt-- == 1) d(this.a, b);");
196-
builder.process(&closure.function)?.finish(
196+
builder.process(&closure.function, None)?.finish(
197197
"function",
198198
"f",
199199
ExportedShim::TableElement(&mut shim),

crates/cli-support/src/js/js2rust.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,22 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
7575

7676
/// Generates all bindings necessary for the signature in `Function`,
7777
/// creating necessary argument conversions and return value processing.
78-
pub fn process(&mut self, function: &Function) -> Result<&mut Self, Error> {
79-
for arg in function.arguments.iter() {
80-
self.argument(arg)?;
78+
pub fn process<'c, I>(
79+
&mut self,
80+
function: &Function,
81+
opt_arg_names: I,
82+
) -> Result<&mut Self, Error>
83+
where
84+
I: Into<Option<&'c Vec<String>>>,
85+
{
86+
if let Some(arg_names) = opt_arg_names.into() {
87+
for (arg, arg_name) in function.arguments.iter().zip(arg_names) {
88+
self.argument(arg, arg_name.as_str())?;
89+
}
90+
} else {
91+
for arg in function.arguments.iter() {
92+
self.argument(arg, None)?;
93+
}
8194
}
8295
self.ret(&function.ret)?;
8396
Ok(self)
@@ -138,15 +151,22 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
138151
self
139152
}
140153

141-
fn abi_arg(&mut self) -> String {
142-
let s = format!("arg{}", self.arg_idx);
154+
fn abi_arg(&mut self, opt_arg_name: Option<&str>) -> String {
155+
let ret = if let Some(x) = opt_arg_name {
156+
x.into()
157+
} else {
158+
format!("arg{}", self.arg_idx)
159+
};
143160
self.arg_idx += 1;
144-
s
161+
ret
145162
}
146163

147-
pub fn argument(&mut self, arg: &Descriptor) -> Result<&mut Self, Error> {
164+
pub fn argument<'c, I>(&mut self, arg: &Descriptor, opt_arg_name: I) -> Result<&mut Self, Error>
165+
where
166+
I: Into<Option<&'c str>>,
167+
{
148168
let i = self.arg_idx;
149-
let name = self.abi_arg();
169+
let name = self.abi_arg(opt_arg_name.into());
150170

151171
let (arg, optional) = match arg {
152172
Descriptor::Option(t) => (&**t, true),

crates/cli-support/src/js/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2498,7 +2498,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
24982498
}
24992499

25002500
let (js, ts, js_doc) = Js2Rust::new(&export.function.name, self.cx)
2501-
.process(descriptor.unwrap_function())?
2501+
.process(descriptor.unwrap_function(), &export.function.arg_names)?
25022502
.finish(
25032503
"function",
25042504
&format!("wasm.{}", export.function.name),
@@ -2554,7 +2554,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
25542554
} else {
25552555
None
25562556
})
2557-
.process(descriptor.unwrap_function())?
2557+
.process(descriptor.unwrap_function(), &export.function.arg_names)?
25582558
.finish(
25592559
"",
25602560
&format!("wasm.{}", wasm_name),
@@ -2772,7 +2772,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
27722772
let setter = ExportedShim::Named(&wasm_setter);
27732773
let mut cx = Js2Rust::new(&field.name, self.cx);
27742774
cx.method(true, false)
2775-
.argument(&descriptor)?
2775+
.argument(&descriptor, None)?
27762776
.ret(&Descriptor::Unit)?;
27772777
ts_dst.push_str(&format!(
27782778
"\n {}{}: {};",

crates/cli-support/src/js/rust2js.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
285285
} else {
286286
builder.rust_argument("this.a");
287287
}
288-
builder.rust_argument("this.b").process(f)?.finish(
288+
builder.rust_argument("this.b").process(f, None)?.finish(
289289
"function",
290290
"this.f",
291291
ExportedShim::TableElement(&mut shim),

crates/shared/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ macro_rules! shared_api {
106106
}
107107

108108
struct Function<'a> {
109+
arg_names: Vec<String>,
109110
name: &'a str,
110111
}
111112

tests/wasm/arg_names.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const wasm = require('wasm-bindgen-test.js');
2+
const assert = require('assert');
3+
4+
const ARGUMENT_NAMES = /([^\s,]+)/g;
5+
const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
6+
7+
// https://stackoverflow.com/q/1007981/210304
8+
function getArgNames(func) {
9+
let fnStr = func.toString().replace(STRIP_COMMENTS, '');
10+
let result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
11+
return result === null ? [] : result;
12+
}
13+
14+
exports.js_arg_names = () => {
15+
assert.deepEqual(getArgNames(wasm.fn_with_many_args), ['_a', '_b', '_c', '_d']);
16+
};

tests/wasm/arg_names.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use wasm_bindgen::prelude::*;
2+
use wasm_bindgen_test::*;
3+
4+
#[wasm_bindgen(module = "tests/wasm/arg_names.js")]
5+
extern "C" {
6+
fn js_arg_names();
7+
}
8+
9+
#[wasm_bindgen]
10+
pub fn fn_with_many_args(_a: i32, _b: i32, _c: i32, _d: i32) {}
11+
12+
#[wasm_bindgen_test]
13+
fn rust_arg_names() {
14+
js_arg_names();
15+
}

tests/wasm/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ extern crate serde_derive;
1313
use wasm_bindgen::prelude::*;
1414

1515
pub mod api;
16+
pub mod arg_names;
1617
pub mod char;
1718
pub mod classes;
1819
pub mod closures;

0 commit comments

Comments
 (0)