mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-17 02:30:50 +00:00
Merge pull request #726 from derekdreery/variadic_js_functions
Support variadic javascript function parameters
This commit is contained in:
commit
1a00e94324
@ -85,6 +85,7 @@ pub struct ImportFunction {
|
||||
pub rust_name: Ident,
|
||||
pub js_ret: Option<syn::Type>,
|
||||
pub catch: bool,
|
||||
pub variadic: bool,
|
||||
pub structural: bool,
|
||||
pub kind: ImportFunctionKind,
|
||||
pub shim: Ident,
|
||||
@ -463,6 +464,7 @@ impl ImportFunction {
|
||||
shared::ImportFunction {
|
||||
shim: self.shim.to_string(),
|
||||
catch: self.catch,
|
||||
variadic: self.variadic,
|
||||
method,
|
||||
structural: self.structural,
|
||||
function: self.function.shared(),
|
||||
|
@ -1733,7 +1733,6 @@ impl<'a> Context<'a> {
|
||||
}
|
||||
|
||||
fn global(&mut self, s: &str) {
|
||||
let s = s;
|
||||
let s = s.trim();
|
||||
|
||||
// Ensure a blank line between adjacent items, and ensure everything is
|
||||
@ -1963,8 +1962,9 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
|
||||
let js = Rust2Js::new(self.cx)
|
||||
.catch(import.catch)
|
||||
.variadic(import.variadic)
|
||||
.process(descriptor.unwrap_function())?
|
||||
.finish(&target);
|
||||
.finish(&target)?;
|
||||
self.cx.export(&import.shim, &js, None);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use failure::Error;
|
||||
use failure::{self, Error};
|
||||
|
||||
use super::{Context, Js2Rust};
|
||||
use descriptor::{Descriptor, Function};
|
||||
@ -36,6 +36,9 @@ pub struct Rust2Js<'a, 'b: 'a> {
|
||||
|
||||
/// Whether or not we're catching JS exceptions
|
||||
catch: bool,
|
||||
|
||||
/// Whether or not the last argument is a slice representing variadic arguments.
|
||||
variadic: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
@ -50,6 +53,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
arg_idx: 0,
|
||||
ret_expr: String::new(),
|
||||
catch: false,
|
||||
variadic: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,6 +66,15 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn variadic(&mut self, variadic: bool) -> &mut Self {
|
||||
if variadic {
|
||||
self.cx.expose_uint32_memory();
|
||||
self.cx.expose_add_heap_object();
|
||||
}
|
||||
self.variadic = variadic;
|
||||
self
|
||||
}
|
||||
|
||||
/// Generates all bindings necessary for the signature in `Function`,
|
||||
/// creating necessary argument conversions and return value processing.
|
||||
pub fn process(&mut self, function: &Function) -> Result<&mut Self, Error> {
|
||||
@ -72,6 +85,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Get a generated name for an argument.
|
||||
fn shim_argument(&mut self) -> String {
|
||||
let s = format!("arg{}", self.arg_idx);
|
||||
self.arg_idx += 1;
|
||||
@ -515,7 +529,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn finish(&self, invoc: &str) -> String {
|
||||
pub fn finish(&self, invoc: &str) -> Result<String, Error> {
|
||||
let mut ret = String::new();
|
||||
ret.push_str("function(");
|
||||
ret.push_str(&self.shim_arguments.join(", "));
|
||||
@ -528,10 +542,24 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
ret.push_str(") {\n");
|
||||
ret.push_str(&self.prelude);
|
||||
|
||||
let mut invoc = self.ret_expr.replace(
|
||||
"JS",
|
||||
&format!("{}({})", invoc, self.js_arguments.join(", ")),
|
||||
);
|
||||
let mut invoc = if self.variadic {
|
||||
if self.js_arguments.is_empty() {
|
||||
return Err(failure::err_msg("a function with no arguments cannot be variadic"));
|
||||
}
|
||||
let last_arg = self.js_arguments.len() - 1; // check implies >= 0
|
||||
self.ret_expr.replace(
|
||||
"JS",
|
||||
&format!("{}({}, ...{})",
|
||||
invoc,
|
||||
self.js_arguments[..last_arg].join(", "),
|
||||
self.js_arguments[last_arg])
|
||||
)
|
||||
} else {
|
||||
self.ret_expr.replace(
|
||||
"JS",
|
||||
&format!("{}({})", invoc, self.js_arguments.join(", ")),
|
||||
)
|
||||
};
|
||||
if self.catch {
|
||||
let catch = "\
|
||||
const view = getUint32Memory();\n\
|
||||
@ -566,7 +594,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
ret.push_str(&invoc);
|
||||
|
||||
ret.push_str("\n}\n");
|
||||
return ret;
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn global_idx(&mut self) -> usize {
|
||||
|
@ -183,6 +183,14 @@ impl BindgenAttrs {
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Whether the variadic attributes is present
|
||||
fn variadic(&self) -> bool {
|
||||
self.attrs.iter().any(|a| match *a {
|
||||
BindgenAttr::Variadic => true,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl syn::synom::Synom for BindgenAttrs {
|
||||
@ -219,6 +227,7 @@ pub enum BindgenAttr {
|
||||
JsName(String),
|
||||
JsClass(String),
|
||||
Extends(Ident),
|
||||
Variadic,
|
||||
}
|
||||
|
||||
impl syn::synom::Synom for BindgenAttr {
|
||||
@ -304,6 +313,8 @@ impl syn::synom::Synom for BindgenAttr {
|
||||
ns: call!(term2ident) >>
|
||||
(ns)
|
||||
)=> { BindgenAttr::Extends }
|
||||
|
|
||||
call!(term, "variadic") => { |_| BindgenAttr::Variadic }
|
||||
));
|
||||
}
|
||||
|
||||
@ -365,6 +376,7 @@ impl<'a> ConvertToAst<()> for &'a mut syn::ItemStruct {
|
||||
let getter = shared::struct_field_get(&ident, &name_str);
|
||||
let setter = shared::struct_field_set(&ident, &name_str);
|
||||
let opts = BindgenAttrs::find(&mut field.attrs)?;
|
||||
assert_not_variadic(&opts, &field)?;
|
||||
let comments = extract_doc_comments(&field.attrs);
|
||||
fields.push(ast::StructField {
|
||||
name: name.clone(),
|
||||
@ -395,6 +407,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
|
||||
) -> Result<Self::Target, Diagnostic> {
|
||||
let default_name = self.ident.to_string();
|
||||
let js_name = opts.js_name().unwrap_or(&default_name);
|
||||
|
||||
let wasm = function_from_decl(
|
||||
js_name,
|
||||
self.decl.clone(),
|
||||
@ -404,6 +417,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
|
||||
None,
|
||||
)?.0;
|
||||
let catch = opts.catch();
|
||||
let variadic = opts.variadic();
|
||||
let js_ret = if catch {
|
||||
// TODO: this assumes a whole bunch:
|
||||
//
|
||||
@ -533,6 +547,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
|
||||
kind,
|
||||
js_ret,
|
||||
catch,
|
||||
variadic,
|
||||
structural: opts.structural(),
|
||||
rust_name: self.ident.clone(),
|
||||
shim: Ident::new(&shim, Span::call_site()),
|
||||
@ -545,6 +560,7 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemType {
|
||||
type Target = ast::ImportKind;
|
||||
|
||||
fn convert(self, attrs: BindgenAttrs) -> Result<Self::Target, Diagnostic> {
|
||||
assert_not_variadic(&attrs, &self)?;
|
||||
let js_name = attrs
|
||||
.js_name()
|
||||
.map_or_else(|| self.ident.to_string(), |s| s.to_string());
|
||||
@ -570,6 +586,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemSt
|
||||
if self.mutability.is_some() {
|
||||
bail_span!(self.mutability, "cannot import mutable globals yet")
|
||||
}
|
||||
assert_not_variadic(&opts, &self)?;
|
||||
let default_name = self.ident.to_string();
|
||||
let js_name = opts.js_name().unwrap_or(&default_name);
|
||||
let shim = format!(
|
||||
@ -604,6 +621,7 @@ impl ConvertToAst<BindgenAttrs> for syn::ItemFn {
|
||||
if self.unsafety.is_some() {
|
||||
bail_span!(self.unsafety, "can only #[wasm_bindgen] safe functions");
|
||||
}
|
||||
assert_not_variadic(&attrs, &self)?;
|
||||
|
||||
let default_name = self.ident.to_string();
|
||||
let name = attrs.js_name().unwrap_or(&default_name);
|
||||
@ -1074,6 +1092,15 @@ fn assert_no_lifetimes(decl: &syn::FnDecl) -> Result<(), Diagnostic> {
|
||||
Diagnostic::from_vec(walk.diagnostics)
|
||||
}
|
||||
|
||||
/// This method always fails if the BindgenAttrs contain variadic
|
||||
fn assert_not_variadic(attrs: &BindgenAttrs, span: &dyn ToTokens) -> Result<(), Diagnostic> {
|
||||
if attrs.variadic() {
|
||||
bail_span!(span, "the `variadic` attribute can only be applied to imported \
|
||||
(`extern`) functions")
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// If the path is a single ident, return it.
|
||||
fn extract_path_ident(path: &syn::Path) -> Result<Ident, Diagnostic> {
|
||||
if path.leading_colon.is_some() {
|
||||
|
@ -43,6 +43,7 @@ pub enum ImportKind {
|
||||
pub struct ImportFunction {
|
||||
pub shim: String,
|
||||
pub catch: bool,
|
||||
pub variadic: bool,
|
||||
pub method: Option<MethodData>,
|
||||
pub structural: bool,
|
||||
pub function: Function,
|
||||
|
@ -277,6 +277,7 @@ impl<'src> FirstPassRecord<'src> {
|
||||
},
|
||||
rust_name: rust_ident(rust_name),
|
||||
js_ret: js_ret.clone(),
|
||||
variadic: false,
|
||||
catch,
|
||||
structural,
|
||||
shim:{
|
||||
|
@ -42,6 +42,7 @@
|
||||
- [`module = "blah"`](./reference/attributes/on-js-imports/module.md)
|
||||
- [`static_method_of = Blah`](./reference/attributes/on-js-imports/static_method_of.md)
|
||||
- [`structural`](./reference/attributes/on-js-imports/structural.md)
|
||||
- [variadic](./reference/attributes/on-js-imports/variadic.md)
|
||||
- [On Rust Exports](./reference/attributes/on-rust-exports/index.md)
|
||||
- [`constructor`](./reference/attributes/on-rust-exports/constructor.md)
|
||||
- [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md)
|
||||
|
38
guide/src/reference/attributes/on-js-imports/variadic.md
Normal file
38
guide/src/reference/attributes/on-js-imports/variadic.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Variadic Parameters
|
||||
|
||||
In javascript, both the types of function arguments, and the number of function arguments are
|
||||
dynamic. For example
|
||||
|
||||
```js
|
||||
function sum(...rest) {
|
||||
let i;
|
||||
// the old way
|
||||
let old_way = 0;
|
||||
for (i=0; i<arguments.length; i++) {
|
||||
old_way += arguments[i];
|
||||
}
|
||||
// the new way
|
||||
let new_way = 0;
|
||||
for (i=0; i<rest.length; i++) {
|
||||
new_way += rest[i];
|
||||
}
|
||||
// both give the same answer
|
||||
assert(old_way === new_way);
|
||||
return new_way;
|
||||
}
|
||||
```
|
||||
|
||||
This function doesn't translate directly into rust, since we don't currently support variadic
|
||||
arguments on the wasm target. To bind to it, we use a slice as the last argument, and annotate the
|
||||
function as variadic:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn sum(args: &[i32]) -> i32;
|
||||
}
|
||||
```
|
||||
|
||||
when we call this function, the last argument will be expanded as the javascript expects.
|
||||
|
@ -64,6 +64,10 @@ extern {
|
||||
fn new() -> Awesome;
|
||||
#[wasm_bindgen(method)]
|
||||
fn get_internal(this: &Awesome) -> u32;
|
||||
// We can call javascript functions that have a dynamic number of arguments,
|
||||
// e.g. rust `sum(&[1, 2, 3])` will be called like `sum(1, 2, 3)`
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn sum(vals: &[u32]) -> u32;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
@ -143,5 +147,13 @@ export class Awesome {
|
||||
}
|
||||
}
|
||||
|
||||
export function sum(...args) {
|
||||
let answer = 0;
|
||||
for(var i=0; i<args.length; i++) {
|
||||
answer += args[i];
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
booted.then(main);
|
||||
```
|
||||
|
@ -31,3 +31,4 @@ pub mod slice;
|
||||
pub mod structural;
|
||||
pub mod u64;
|
||||
pub mod validate_prt;
|
||||
pub mod variadic;
|
||||
|
59
tests/wasm/variadic.js
Normal file
59
tests/wasm/variadic.js
Normal file
@ -0,0 +1,59 @@
|
||||
const assert = require('assert');
|
||||
|
||||
// a function for testing numbers
|
||||
function variadic_sum(...args) {
|
||||
let answer = 0;
|
||||
for(var i=0; i<args.length; i++) {
|
||||
answer += args[i];
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
exports.variadic_sum_u8 = variadic_sum;
|
||||
exports.variadic_sum_u16 = variadic_sum;
|
||||
exports.variadic_sum_u32 = variadic_sum;
|
||||
exports.variadic_sum_u64 = variadic_sum;
|
||||
exports.variadic_sum_i8 = variadic_sum;
|
||||
exports.variadic_sum_i16 = variadic_sum;
|
||||
exports.variadic_sum_i32 = variadic_sum;
|
||||
exports.variadic_sum_i64 = variadic_sum;
|
||||
exports.variadic_sum_f32 = variadic_sum;
|
||||
exports.variadic_sum_f64 = variadic_sum;
|
||||
exports.variadic_sum_rest_vec = variadic_sum;
|
||||
|
||||
// a function for testing nullable numbers
|
||||
function variadic_sum_opt(...args) {
|
||||
let answer = 0;
|
||||
for(var i=0; i<args.length; i++) {
|
||||
if(args[i] != null) {
|
||||
answer += args[i];
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
exports.variadic_sum_opt = variadic_sum_opt;
|
||||
|
||||
// a function for testing strings
|
||||
function variadic_concat(...args) {
|
||||
let answer = "";
|
||||
for(var i=0; i<args.length; i++) {
|
||||
answer = `${answer}${args[i]}`;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
exports.variadic_concat_str = variadic_concat;
|
||||
exports.variadic_concat_string = variadic_concat;
|
||||
|
||||
// a test that takes any type of arguments (for testing JsValue).
|
||||
function variadic_compare_pairs(...args) {
|
||||
assert(args.length % 2 == 0, "args must be sequence of pairs");
|
||||
for(var i=0; i<args.length; i++) {
|
||||
const first = args[i++];
|
||||
const second = args[i];
|
||||
assert.equal(first, second);
|
||||
}
|
||||
}
|
||||
|
||||
exports.variadic_compare_pairs = variadic_compare_pairs;
|
135
tests/wasm/variadic.rs
Normal file
135
tests/wasm/variadic.rs
Normal file
@ -0,0 +1,135 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/variadic.js")]
|
||||
extern {
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_u8(first: u8, second: u8, rest: &[u8]) -> u8;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_u16(first: u16, second: u16, rest: &[u16]) -> u16;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_u32(first: u32, second: u32, rest: &[u32]) -> u32;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_u64(first: u64, second: u64, rest: &[u64]) -> u64;
|
||||
//#[wasm_bindgen(variadic)]
|
||||
//fn variadic_sum_usize(first: usize, second: usize, rest: &[usize]) -> usize;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_i8(first: i8, second: i8, rest: &[i8]) -> i8;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_i16(first: i16, second: i16, rest: &[i16]) -> i16;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_i32(first: i32, second: i32, rest: &[i32]) -> i32;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_i64(first: i64, second: i64, rest: &[i64]) -> i64;
|
||||
//#[wasm_bindgen(variadic)]
|
||||
//fn variadic_sum_isize(first: isize, second: isize, rest: &[isize]) -> isize;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_f32(first: f32, second: f32, rest: &[f32]) -> f32;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_f64(first: f64, second: f64, rest: &[f64]) -> f64;
|
||||
//#[wasm_bindgen(variadic)]
|
||||
//fn variadic_sum_opt(first: Option<u32>, second: Option<u32>, rest: &[Option<u32>]) -> u32;
|
||||
//#[wasm_bindgen(variadic)]
|
||||
//fn variadic_concat_str(first: &str, second: &str, rest: &[&str]) -> String;
|
||||
//#[wasm_bindgen(variadic)]
|
||||
//fn variadic_concat_string(first: String,
|
||||
// second: String,
|
||||
// rest: Vec<String>) -> String;
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn variadic_sum_rest_vec(first: u8, second: u8, rest: Vec<u8>) -> u8;
|
||||
//#[wasm_bindgen(variadic)]
|
||||
//fn variadic_compare_pairs(first: JsValue, second: JsValue, rest: &[JsValue]);
|
||||
//TODO imported type
|
||||
}
|
||||
|
||||
// ints
|
||||
|
||||
macro_rules! variadic_test_int {
|
||||
($fn_name:ident, $extern_name:ident) => {
|
||||
#[wasm_bindgen_test]
|
||||
fn $fn_name() {
|
||||
assert_eq!($extern_name(1, 2, &[]), 3);
|
||||
assert_eq!($extern_name(1, 2, &[3]), 6);
|
||||
assert_eq!($extern_name(1, 2, &[3, 4]), 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The <int>64 tests throw js `Cannot mix BigInt and other types, use explicit conversions`
|
||||
variadic_test_int!(u8, variadic_sum_u8);
|
||||
variadic_test_int!(u16, variadic_sum_u16);
|
||||
variadic_test_int!(u32, variadic_sum_u32);
|
||||
//variadic_test_int!(u64, variadic_sum_u64);
|
||||
//variadic_test_int!(usize, variadic_sum_usize);
|
||||
variadic_test_int!(i8, variadic_sum_i8);
|
||||
variadic_test_int!(i16, variadic_sum_i16);
|
||||
variadic_test_int!(i32, variadic_sum_i32);
|
||||
//variadic_test_int!(i64, variadic_sum_i64);
|
||||
//variadic_test_int!(isize, variadic_sum_isize);
|
||||
|
||||
// floats
|
||||
|
||||
macro_rules! variadic_test_float {
|
||||
($fn_name:ident, $extern_name:ident) => {
|
||||
#[wasm_bindgen_test]
|
||||
fn $fn_name() {
|
||||
assert_eq!($extern_name(1., 2., &[]), 3.);
|
||||
assert_eq!($extern_name(1., 2., &[3.]), 6.);
|
||||
assert_eq!($extern_name(1., 2., &[3., 4.]), 10.);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variadic_test_float!(f32, variadic_sum_f32);
|
||||
variadic_test_float!(f64, variadic_sum_f64);
|
||||
|
||||
// strings
|
||||
|
||||
// `the trait `wasm_bindgen::convert::IntoWasmAbi` is not implemented for `&[&str]`
|
||||
/*
|
||||
#[wasm_bindgen_test]
|
||||
fn str() {
|
||||
assert_eq!(variadic_concat_str("a ", "test", &[]), "a test");
|
||||
assert_eq!(variadic_concat_str("a", "nother ", &["test"]), "another test");
|
||||
assert_eq!(variadic_concat_str("yet ", "a", &["nother ", "test"]), "yet another test");
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn string() {
|
||||
assert_eq!(variadic_concat_string("a ".into(), "test".into(), vec![]), "a test");
|
||||
assert_eq!(variadic_concat_string("a".into(), "nother ".into(), vec!["test".into()]),
|
||||
"another test");
|
||||
assert_eq!(variadic_concat_string("yet ".into(),
|
||||
"a".into(),
|
||||
vec!["nother ".into(), "test".into()]),
|
||||
"yet another test");
|
||||
}
|
||||
*/
|
||||
|
||||
// options
|
||||
|
||||
/*
|
||||
#[wasm_bindgen_test]
|
||||
fn opt() {
|
||||
assert_eq!(variadic_sum_opt(Some(1), None, &[]), 1);
|
||||
assert_eq!(variadic_sum_opt(Some(1), None, &[Some(2)]), 3);
|
||||
assert_eq!(variadic_sum_opt(Some(1), None, &[None, Some(2)]), 3);
|
||||
}
|
||||
*/
|
||||
|
||||
// vec not slice
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn rest_vec() {
|
||||
assert_eq!(variadic_sum_rest_vec(1, 2, vec![]), 3);
|
||||
assert_eq!(variadic_sum_rest_vec(1, 2, vec![3]), 6);
|
||||
assert_eq!(variadic_sum_rest_vec(1, 2, vec![3, 4]), 10);
|
||||
}
|
||||
|
||||
// JsValue
|
||||
//#[wasm_bindgen_test]
|
||||
//fn jsvalue() {
|
||||
// variadic_compare_pairs_jsvalue(true, true, vec![]);
|
||||
// variadic_compare_pairs_jsvalue(false, false, vec![3, 3]);
|
||||
//}
|
||||
|
Loading…
x
Reference in New Issue
Block a user