From 79f53b567b894833695779d0025224fff52c8a98 Mon Sep 17 00:00:00 2001 From: Liigo Zhuang Date: Tue, 10 Jul 2018 13:23:26 +0800 Subject: [PATCH 01/20] js::DataView binding --- src/js.rs | 146 +++++++++++++++++++++++++++++++ tests/all/js_globals/DataView.rs | 54 ++++++++++++ tests/all/js_globals/mod.rs | 1 + 3 files changed, 201 insertions(+) create mode 100644 tests/all/js_globals/DataView.rs diff --git a/src/js.rs b/src/js.rs index 208ffe87..a1b85978 100644 --- a/src/js.rs +++ b/src/js.rs @@ -378,6 +378,152 @@ extern "C" { pub fn value_of(this: &Boolean) -> bool; } +// DataView +#[wasm_bindgen] +extern "C" { + pub type DataView; + + /// The `DataView` view provides a low-level interface for reading and + /// writing multiple number types in an `ArrayBuffer` irrespective of the + /// platform's endianness. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView + #[wasm_bindgen(constructor)] + pub fn new(buffer: &ArrayBuffer, byteOffset: usize, byteLength: usize) -> DataView; + + /// The ArrayBuffer referenced by this view. Fixed at construction time and thus read only. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/buffer + #[wasm_bindgen(method)] + pub fn buffer(this: &DataView) -> ArrayBuffer; + + /// The length (in bytes) of this view from the start of its ArrayBuffer. + /// Fixed at construction time and thus read only. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteLength + #[wasm_bindgen(method, js_name = byteLength)] + pub fn byte_length(this: &DataView) -> usize; + + /// The offset (in bytes) of this view from the start of its ArrayBuffer. + /// Fixed at construction time and thus read only. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteOffset + #[wasm_bindgen(method, js_name = byteOffset)] + pub fn byte_offset(this: &DataView) -> usize; + + /// The getInt8() method gets a signed 8-bit integer (byte) at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt8 + #[wasm_bindgen(method, js_name = getInt8)] + pub fn get_int8(this: &DataView, byte_offset: usize) -> i8; + + /// The getInt8() method gets a signed 8-bit integer (byte) at the specified + /// byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint8 + #[wasm_bindgen(method, js_name = getUint8)] + pub fn get_uint8(this: &DataView, byte_offset: usize) -> u8; + + /// The getInt16() method gets a signed 16-bit integer (byte) at the specified + /// byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt16 + #[wasm_bindgen(method, js_name = getInt16)] + pub fn get_int16(this: &DataView, byte_offset: usize) -> i16; + + /// The getUint16() an unsigned 16-bit integer (unsigned byte) at the specified + /// byte offset from the start of the view. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint16 + #[wasm_bindgen(method, js_name = getUint16)] + pub fn get_uint16(this: &DataView, byte_offset: usize) -> u16; + + /// The getInt32() method gets a signed 16-bit integer (byte) at the specified + /// byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt32 + #[wasm_bindgen(method, js_name = getInt32)] + pub fn get_int32(this: &DataView, byte_offset: usize) -> i32; + + /// The getUint32() an unsigned 16-bit integer (unsigned byte) at the specified + /// byte offset from the start of the view. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint32 + #[wasm_bindgen(method, js_name = getUint32)] + pub fn get_uint32(this: &DataView, byte_offset: usize) -> u32; + + /// The getFloat32() method gets a signed 32-bit float (float) at the specified + /// byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat32 + #[wasm_bindgen(method, js_name = getFloat32)] + pub fn get_float32(this: &DataView, byte_offset: usize) -> f32; + + /// The getFloat64() method gets a signed 32-bit float (float) at the specified + /// byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat64 + #[wasm_bindgen(method, js_name = getFloat64)] + pub fn get_float64(this: &DataView, byte_offset: usize) -> f64; + + /// The setInt8() method stores a signed 8-bit integer (byte) value at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt8 + #[wasm_bindgen(method, js_name = setInt8)] + pub fn set_int8(this: &DataView, byte_offset: usize, value: i8); + + /// The setUint8() method stores an unsigned 8-bit integer (byte) value at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint8 + #[wasm_bindgen(method, js_name = setUint8)] + pub fn set_uint8(this: &DataView, byte_offset: usize, value: u8); + + /// The setInt16() method stores a signed 16-bit integer (byte) value at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt16 + #[wasm_bindgen(method, js_name = setInt16)] + pub fn set_int16(this: &DataView, byte_offset: usize, value: i16); + + /// The setUint16() method stores an unsigned 16-bit integer (byte) value at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint16 + #[wasm_bindgen(method, js_name = setUint16)] + pub fn set_uint16(this: &DataView, byte_offset: usize, value: u16); + + /// The setInt32() method stores a signed 32-bit integer (byte) value at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt32 + #[wasm_bindgen(method, js_name = setInt32)] + pub fn set_int32(this: &DataView, byte_offset: usize, value: i32); + + /// The setUint32() method stores an unsigned 32-bit integer (byte) value at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint32 + #[wasm_bindgen(method, js_name = setUint32)] + pub fn set_uint32(this: &DataView, byte_offset: usize, value: u32); + + /// The setFloat32() method stores a signed 32-bit float (float) value at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat32 + #[wasm_bindgen(method, js_name = setFloat32)] + pub fn set_float32(this: &DataView, byte_offset: usize, value: f32); + + /// The setFloat64() method stores a signed 64-bit float (float) value at the + /// specified byte offset from the start of the DataView. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat64 + #[wasm_bindgen(method, js_name = setFloat64)] + pub fn set_float64(this: &DataView, byte_offset: usize, value: f64); +} + // Error #[wasm_bindgen] extern "C" { diff --git a/tests/all/js_globals/DataView.rs b/tests/all/js_globals/DataView.rs new file mode 100644 index 00000000..f577b5a3 --- /dev/null +++ b/tests/all/js_globals/DataView.rs @@ -0,0 +1,54 @@ +#![allow(non_snake_case)] + +use super::project; + +#[test] +fn test() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js::{ArrayBuffer, DataView}; + + #[wasm_bindgen] + pub fn test_data_view(buffer: &ArrayBuffer, offset: usize, len: usize) { + let v = DataView::new(buffer, offset, len); + assert_eq!(v.byte_offset(), offset); + assert_eq!(v.byte_length(), len); + assert_eq!(v.get_int8(0), 3); + assert_eq!(v.get_uint8(0), 3); + + v.set_int8(0, 42); + assert_eq!(v.get_int8(0), 42); + v.set_uint8(0, 255); + assert_eq!(v.get_uint8(0), 255); + v.set_int16(0, 32767); + assert_eq!(v.get_int16(0), 32767); + v.set_uint16(0, 65535); + assert_eq!(v.get_uint16(0), 65535); + v.set_int32(0, 123456789); + assert_eq!(v.get_int32(0), 123456789); + v.set_uint32(0, 3_123_456_789); + assert_eq!(v.get_uint32(0), 3_123_456_789); + v.set_float32(0, 100.123); + assert_eq!(v.get_float32(0), 100.123); + v.set_float64(0, 123456789.123456); + assert_eq!(v.get_float64(0), 123456789.123456); + + v.set_int8(0, 4+2); + } + "#) + .file("test.js", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + var buffer = Uint8Array.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + wasm.test_data_view(buffer, 2, 8); + assert.equal(buffer[2], 42); + } + "#) + .test() +} diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 2af15330..211df89e 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -6,6 +6,7 @@ mod Array; mod ArrayBuffer; mod ArrayIterator; mod Boolean; +mod DataView; mod Date; mod Error; mod Function; From e568a2369fa170653ef0f38d791a2d065629be85 Mon Sep 17 00:00:00 2001 From: Liigo Zhuang Date: Wed, 11 Jul 2018 13:03:25 +0800 Subject: [PATCH 02/20] `buffer` / `byteOffset` / `byteLenght` is property getter --- src/js.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js.rs b/src/js.rs index a1b85978..dca554c4 100644 --- a/src/js.rs +++ b/src/js.rs @@ -394,21 +394,21 @@ extern "C" { /// The ArrayBuffer referenced by this view. Fixed at construction time and thus read only. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/buffer - #[wasm_bindgen(method)] + #[wasm_bindgen(method, getter, structural)] pub fn buffer(this: &DataView) -> ArrayBuffer; /// The length (in bytes) of this view from the start of its ArrayBuffer. /// Fixed at construction time and thus read only. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteLength - #[wasm_bindgen(method, js_name = byteLength)] + #[wasm_bindgen(method, getter, structural, js_name = byteLength)] pub fn byte_length(this: &DataView) -> usize; /// The offset (in bytes) of this view from the start of its ArrayBuffer. /// Fixed at construction time and thus read only. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteOffset - #[wasm_bindgen(method, js_name = byteOffset)] + #[wasm_bindgen(method, getter, structural, js_name = byteOffset)] pub fn byte_offset(this: &DataView) -> usize; /// The getInt8() method gets a signed 8-bit integer (byte) at the From 823e5a4fd907584fa02c310b7682de7e321f6ba1 Mon Sep 17 00:00:00 2001 From: Liigo Zhuang Date: Wed, 11 Jul 2018 14:01:41 +0800 Subject: [PATCH 03/20] fix test --- tests/all/js_globals/DataView.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/all/js_globals/DataView.rs b/tests/all/js_globals/DataView.rs index f577b5a3..7fb70111 100644 --- a/tests/all/js_globals/DataView.rs +++ b/tests/all/js_globals/DataView.rs @@ -17,9 +17,9 @@ fn test() { let v = DataView::new(buffer, offset, len); assert_eq!(v.byte_offset(), offset); assert_eq!(v.byte_length(), len); - assert_eq!(v.get_int8(0), 3); - assert_eq!(v.get_uint8(0), 3); - + assert_eq!(v.get_int8(0), 2); + assert_eq!(v.get_uint8(0), 2); + v.set_int8(0, 42); assert_eq!(v.get_int8(0), 42); v.set_uint8(0, 255); @@ -37,7 +37,7 @@ fn test() { v.set_float64(0, 123456789.123456); assert_eq!(v.get_float64(0), 123456789.123456); - v.set_int8(0, 4+2); + v.set_int8(0, 42); } "#) .file("test.js", r#" @@ -45,9 +45,10 @@ fn test() { import * as wasm from "./out"; export function test() { - var buffer = Uint8Array.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); - wasm.test_data_view(buffer, 2, 8); - assert.equal(buffer[2], 42); + var bytes = new Int8Array(10); + bytes[2] = 2; + wasm.test_data_view(bytes.buffer, 2, 8); + assert.equal(bytes[2], 42); } "#) .test() From e666371ae39b72d5e3491b36828eaa976809fd05 Mon Sep 17 00:00:00 2001 From: Liigo Zhuang Date: Thu, 12 Jul 2018 09:54:58 +0800 Subject: [PATCH 04/20] some fix --- src/js.rs | 2 +- tests/all/js_globals/DataView.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js.rs b/src/js.rs index dca554c4..fd6afa6c 100644 --- a/src/js.rs +++ b/src/js.rs @@ -418,7 +418,7 @@ extern "C" { #[wasm_bindgen(method, js_name = getInt8)] pub fn get_int8(this: &DataView, byte_offset: usize) -> i8; - /// The getInt8() method gets a signed 8-bit integer (byte) at the specified + /// The getUint8() method gets a unsigned 8-bit integer (byte) at the specified /// byte offset from the start of the DataView. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint8 diff --git a/tests/all/js_globals/DataView.rs b/tests/all/js_globals/DataView.rs index 7fb70111..ced10a22 100644 --- a/tests/all/js_globals/DataView.rs +++ b/tests/all/js_globals/DataView.rs @@ -45,7 +45,7 @@ fn test() { import * as wasm from "./out"; export function test() { - var bytes = new Int8Array(10); + const bytes = new Int8Array(10); bytes[2] = 2; wasm.test_data_view(bytes.buffer, 2, 8); assert.equal(bytes[2], 42); From 913b487638918864473ffb21726a910c94ac61b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 12 Jul 2018 08:14:53 +0000 Subject: [PATCH 05/20] Bump webpack from 4.15.1 to 4.16.0 Bumps [webpack](https://github.com/webpack/webpack) from 4.15.1 to 4.16.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v4.15.1...v4.16.0) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 274915ec..8d5c20eb 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "selenium-webdriver": "^4.0.0-alpha.1", "ts-loader": "^4.4.2", "typescript": "^2.7.2", - "webpack": "^4.15.1", + "webpack": "^4.16.0", "webpack-cli": "^3.0.8", "webpack-dev-server": "^3.1.4" } diff --git a/yarn.lock b/yarn.lock index 8702f195..b6ad8e4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4150,9 +4150,9 @@ webpack-sources@^1.0.1, webpack-sources@^1.1.0: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^4.15.1: - version "4.15.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.15.1.tgz#dc716779a3b88827c369f18c71a6137fa7e582fd" +webpack@^4.16.0: + version "4.16.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.0.tgz#660dae90890e55b8ed17c6f9d17bebb01dab5b4c" dependencies: "@webassemblyjs/ast" "1.5.13" "@webassemblyjs/helper-module-context" "1.5.13" From a7deb69e80b44b16ce33a31c87e4c5172f69463b Mon Sep 17 00:00:00 2001 From: Tomohide Takao Date: Thu, 12 Jul 2018 22:56:08 +0900 Subject: [PATCH 06/20] Bindings for Array.prototype.reduce(Right) --- src/js.rs | 14 ++++++++ tests/all/js_globals/Array.rs | 66 +++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/src/js.rs b/src/js.rs index fd6afa6c..33524bd2 100644 --- a/src/js.rs +++ b/src/js.rs @@ -240,6 +240,20 @@ extern "C" { #[wasm_bindgen(method)] pub fn push(this: &Array, value: JsValue) -> u32; + /// The reduce() method applies a function against an accumulator and each element in + /// the array (from left to right) to reduce it to a single value. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce + #[wasm_bindgen(method)] + pub fn reduce(this: &Array, predicate: &mut FnMut(JsValue, JsValue, u32, Array) -> JsValue, initial_value: JsValue) -> JsValue; + + /// The reduceRight() method applies a function against an accumulator and each value + /// of the array (from right-to-left) to reduce it to a single value. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight + #[wasm_bindgen(method, js_name = reduceRight)] + pub fn reduce_right(this: &Array, predicate: &mut FnMut(JsValue, JsValue, u32, Array) -> JsValue, initial_value: JsValue) -> JsValue; + /// The reverse() method reverses an array in place. The first array /// element becomes the last, and the last array element becomes the first. /// diff --git a/tests/all/js_globals/Array.rs b/tests/all/js_globals/Array.rs index a8ab5477..c9a0d55b 100644 --- a/tests/all/js_globals/Array.rs +++ b/tests/all/js_globals/Array.rs @@ -830,3 +830,69 @@ fn map() { ) .test() } + +#[test] +fn reduce() { + project() + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + use JsValue; + + #[wasm_bindgen] + pub fn array_reduce(array: &js::Array) -> JsValue { + array.reduce(&mut |ac, cr, _, _| JsValue::from_str(&format!("{}{}", &ac.as_string().unwrap(), &cr.as_string().unwrap().as_str())), JsValue::from_str("")) + } + "#, + ) + .file( + "test.js", + r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.array_reduce(['0', '1', '2', '3', '4']), '01234'); + } + "#, + ) + .test() +} + +#[test] +fn reduce_right() { + project() + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + use JsValue; + + #[wasm_bindgen] + pub fn array_reduce_right(array: &js::Array) -> JsValue { + array.reduce_right(&mut |ac, cr, _, _| JsValue::from_str(&format!("{}{}", &ac.as_string().unwrap(), &cr.as_string().unwrap().as_str())), JsValue::from_str("")) + } + "#, + ) + .file( + "test.js", + r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.array_reduce_right(['0', '1', '2', '3', '4']), '43210'); + } + "#, + ) + .test() +} \ No newline at end of file From 04ad5bc727130ef8284d723d1ca4dea6f2f85fa4 Mon Sep 17 00:00:00 2001 From: Liigo Zhuang Date: Fri, 13 Jul 2018 22:28:07 +0800 Subject: [PATCH 07/20] remove unused `Stack::pop()` (#434) --- src/convert.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/convert.rs b/src/convert.rs index c73a553f..9f0a19a0 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -77,7 +77,6 @@ pub trait RefMutFromWasmAbi: WasmDescribe { pub trait Stack { fn push(&mut self, bits: u32); - fn pop(&mut self) -> u32; } /// An unsafe trait which represents types that are ABI-safe to pass via wasm @@ -428,15 +427,6 @@ impl Stack for GlobalStack { self.next += 1; } } - - fn pop(&mut self) -> u32 { - unsafe { - assert!(self.next < GLOBAL_STACK_CAP); - let ret = GLOBAL_STACK[self.next]; - self.next += 1; - ret - } - } } #[doc(hidden)] From 133706fc5c03439bd04dd47aae8ae455794b2345 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Jul 2018 08:10:51 -0700 Subject: [PATCH 08/20] Remove debug sections by default The changes on master Rust insert debug sections now (yay!) but this means that wasm binaries by default pick up debug sections from the standard library, so let's remove them by default in wasm-bindgen unless `--debug` is passed --- crates/cli-support/Cargo.toml | 2 +- crates/cli-support/src/js/mod.rs | 1 + crates/cli-support/src/lib.rs | 7 +++++++ crates/cli/src/bin/wasm-bindgen.rs | 3 +++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/cli-support/Cargo.toml b/crates/cli-support/Cargo.toml index 7cf552f2..09ef9558 100644 --- a/crates/cli-support/Cargo.toml +++ b/crates/cli-support/Cargo.toml @@ -19,5 +19,5 @@ serde_derive = "1.0" serde_json = "1.0" tempfile = "3.0" wasm-bindgen-shared = { path = "../shared", version = '=0.2.11' } -wasm-gc-api = "0.1" +wasm-gc-api = "0.1.8" wasmi = "0.3" diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index ef47aa55..46c9adcd 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1580,6 +1580,7 @@ impl<'a> Context<'a> { let wasm_bytes = parity_wasm::serialize(module)?; let bytes = wasm_gc::Config::new() .demangle(self.config.demangle) + .keep_debug(self.config.keep_debug || self.config.debug) .gc(&wasm_bytes)?; *self.module = deserialize_buffer(&bytes)?; Ok(()) diff --git a/crates/cli-support/src/lib.rs b/crates/cli-support/src/lib.rs index 410700f3..a9a88769 100644 --- a/crates/cli-support/src/lib.rs +++ b/crates/cli-support/src/lib.rs @@ -31,6 +31,7 @@ pub struct Bindgen { debug: bool, typescript: bool, demangle: bool, + keep_debug: bool, } impl Bindgen { @@ -45,6 +46,7 @@ impl Bindgen { debug: false, typescript: false, demangle: true, + keep_debug: false, } } @@ -93,6 +95,11 @@ impl Bindgen { self } + pub fn keep_debug(&mut self, keep_debug: bool) -> &mut Bindgen { + self.keep_debug = keep_debug; + self + } + pub fn generate>(&mut self, path: P) -> Result<(), Error> { self._generate(path.as_ref()) } diff --git a/crates/cli/src/bin/wasm-bindgen.rs b/crates/cli/src/bin/wasm-bindgen.rs index 606a3fee..996bf5aa 100644 --- a/crates/cli/src/bin/wasm-bindgen.rs +++ b/crates/cli/src/bin/wasm-bindgen.rs @@ -32,6 +32,7 @@ Options: --no-typescript Don't emit a *.d.ts file --debug Include otherwise-extraneous debug checks in output --no-demangle Don't demangle Rust symbol names + --keep-debug Keep debug sections in wasm files -V --version Print the version number of wasm-bindgen "; @@ -47,6 +48,7 @@ struct Args { flag_version: bool, flag_no_demangle: bool, flag_no_modules_global: Option, + flag_keep_debug: bool, arg_input: Option, } @@ -85,6 +87,7 @@ fn rmain(args: &Args) -> Result<(), Error> { .no_modules(args.flag_no_modules) .debug(args.flag_debug) .demangle(!args.flag_no_demangle) + .keep_debug(args.flag_keep_debug) .typescript(typescript); if let Some(ref name) = args.flag_no_modules_global { b.no_modules_global(name); From 1a8490146d42e877e72c72e0d558ebe8e939e1f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 13 Jul 2018 10:13:19 -0500 Subject: [PATCH 09/20] Bump babel-eslint from 8.2.5 to 8.2.6 (#464) Bumps [babel-eslint](https://github.com/babel/babel-eslint) from 8.2.5 to 8.2.6. - [Release notes](https://github.com/babel/babel-eslint/releases) - [Commits](https://github.com/babel/babel-eslint/compare/v8.2.5...v8.2.6) Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 8d5c20eb..51645974 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "devDependencies": { "@types/node": "^10.5.2", - "babel-eslint": "^8.2.5", + "babel-eslint": "^8.2.6", "eslint": "^5.1.0", "geckodriver": "^1.11.0", "selenium-webdriver": "^4.0.0-alpha.1", diff --git a/yarn.lock b/yarn.lock index b6ad8e4a..2de4b8b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -408,15 +408,15 @@ babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-eslint@^8.2.5: - version "8.2.5" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.5.tgz#dc2331c259d36782aa189da510c43dedd5adc7a3" +babel-eslint@^8.2.6: + version "8.2.6" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" dependencies: "@babel/code-frame" "7.0.0-beta.44" "@babel/traverse" "7.0.0-beta.44" "@babel/types" "7.0.0-beta.44" babylon "7.0.0-beta.44" - eslint-scope "~3.7.1" + eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" babylon@7.0.0-beta.44: @@ -1239,7 +1239,7 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -eslint-scope@^3.7.1, eslint-scope@~3.7.1: +eslint-scope@3.7.1, eslint-scope@^3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" dependencies: From 2007fe6b9c9d553edb55e950363ca413cb8be3ed Mon Sep 17 00:00:00 2001 From: Julius Rakow Date: Fri, 13 Jul 2018 17:41:54 +0200 Subject: [PATCH 10/20] guide: bump required nodejs version to 10 (#467) --- guide/src/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide/src/contributing.md b/guide/src/contributing.md index dbf4f6f5..62d2f222 100644 --- a/guide/src/contributing.md +++ b/guide/src/contributing.md @@ -14,7 +14,7 @@ development. [install Rust]: https://www.rust-lang.org/en-US/install.html -2. The tests for this project use Node. Make sure you have node >= 8 installed, +2. The tests for this project use Node. Make sure you have node >= 10 installed, as that is when WebAssembly support was introduced. [Install Node]. [Install Node]: https://nodejs.org/en/ From b2b07093d018234512719736ff0392475a16f575 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Jul 2018 09:49:45 -0700 Subject: [PATCH 11/20] Add `#[inline]` to a number of conversion methods These are all trivial methods and `#[inline]` will help release and non-LTO builds (hopefully most builds from now on) to eliminate these function calls and inline better. --- src/convert.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/convert.rs b/src/convert.rs index 9f0a19a0..65e652cd 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -104,11 +104,15 @@ macro_rules! simple { ($($t:tt)*) => ($( impl IntoWasmAbi for $t { type Abi = $t; + + #[inline] fn into_abi(self, _extra: &mut Stack) -> $t { self } } impl FromWasmAbi for $t { type Abi = $t; + + #[inline] unsafe fn from_abi(js: $t, _extra: &mut Stack) -> $t { js } } )*) @@ -120,6 +124,8 @@ macro_rules! sixtyfour { ($($t:tt)*) => ($( impl IntoWasmAbi for $t { type Abi = WasmSlice; + + #[inline] fn into_abi(self, _extra: &mut Stack) -> WasmSlice { WasmSlice { ptr: self as u32, @@ -130,6 +136,8 @@ macro_rules! sixtyfour { impl FromWasmAbi for $t { type Abi = WasmSlice; + + #[inline] unsafe fn from_abi(js: WasmSlice, _extra: &mut Stack) -> $t { (js.ptr as $t) | ((js.len as $t) << 32) } @@ -143,11 +151,15 @@ macro_rules! as_u32 { ($($t:tt)*) => ($( impl IntoWasmAbi for $t { type Abi = u32; + + #[inline] fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 } } impl FromWasmAbi for $t { type Abi = u32; + + #[inline] unsafe fn from_abi(js: u32, _extra: &mut Stack) -> $t { js as $t } } )*) @@ -158,6 +170,7 @@ as_u32!(i8 u8 i16 u16 isize usize); impl IntoWasmAbi for bool { type Abi = u32; + #[inline] fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 } @@ -166,6 +179,7 @@ impl IntoWasmAbi for bool { impl FromWasmAbi for bool { type Abi = u32; + #[inline] unsafe fn from_abi(js: u32, _extra: &mut Stack) -> bool { js != 0 } @@ -173,6 +187,8 @@ impl FromWasmAbi for bool { impl IntoWasmAbi for char { type Abi = u32; + + #[inline] fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 } @@ -180,6 +196,8 @@ impl IntoWasmAbi for char { impl FromWasmAbi for char { type Abi = u32; + + #[inline] unsafe fn from_abi(js: u32, _extra: &mut Stack) -> char { char::from_u32_unchecked(js) } @@ -223,6 +241,7 @@ macro_rules! vectors { impl IntoWasmAbi for Box<[$t]> { type Abi = WasmSlice; + #[inline] fn into_abi(self, extra: &mut Stack) -> WasmSlice { let ptr = self.as_ptr(); let len = self.len(); @@ -238,6 +257,7 @@ macro_rules! vectors { impl FromWasmAbi for Box<[$t]> { type Abi = WasmSlice; + #[inline] unsafe fn from_abi(js: WasmSlice, extra: &mut Stack) -> Self { let ptr = <*mut $t>::from_abi(js.ptr, extra); let len = js.len as usize; @@ -248,6 +268,7 @@ macro_rules! vectors { impl<'a> IntoWasmAbi for &'a [$t] { type Abi = WasmSlice; + #[inline] fn into_abi(self, extra: &mut Stack) -> WasmSlice { WasmSlice { ptr: self.as_ptr().into_abi(extra), @@ -259,6 +280,7 @@ macro_rules! vectors { impl<'a> IntoWasmAbi for &'a mut [$t] { type Abi = WasmSlice; + #[inline] fn into_abi(self, extra: &mut Stack) -> WasmSlice { (&*self).into_abi(extra) } @@ -268,6 +290,7 @@ macro_rules! vectors { type Abi = WasmSlice; type Anchor = &'static [$t]; + #[inline] unsafe fn ref_from_abi(js: WasmSlice, extra: &mut Stack) -> &'static [$t] { slice::from_raw_parts( <*const $t>::from_abi(js.ptr, extra), @@ -280,6 +303,7 @@ macro_rules! vectors { type Abi = WasmSlice; type Anchor = &'static mut [$t]; + #[inline] unsafe fn ref_mut_from_abi(js: WasmSlice, extra: &mut Stack) -> &'static mut [$t] { @@ -299,6 +323,7 @@ vectors! { if_std! { impl IntoWasmAbi for Vec where Box<[T]>: IntoWasmAbi { type Abi = as IntoWasmAbi>::Abi; + fn into_abi(self, extra: &mut Stack) -> Self::Abi { self.into_boxed_slice().into_abi(extra) } @@ -315,6 +340,7 @@ if_std! { impl IntoWasmAbi for String { type Abi = as IntoWasmAbi>::Abi; + #[inline] fn into_abi(self, extra: &mut Stack) -> Self::Abi { self.into_bytes().into_abi(extra) } @@ -323,6 +349,7 @@ if_std! { impl FromWasmAbi for String { type Abi = as FromWasmAbi>::Abi; + #[inline] unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self { String::from_utf8_unchecked(>::from_abi(js, extra)) } @@ -332,6 +359,7 @@ if_std! { impl<'a> IntoWasmAbi for &'a str { type Abi = <&'a [u8] as IntoWasmAbi>::Abi; + #[inline] fn into_abi(self, extra: &mut Stack) -> Self::Abi { self.as_bytes().into_abi(extra) } @@ -341,6 +369,7 @@ impl RefFromWasmAbi for str { type Abi = <[u8] as RefFromWasmAbi>::Abi; type Anchor = &'static str; + #[inline] unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor { str::from_utf8_unchecked(<[u8]>::ref_from_abi(js, extra)) } @@ -349,6 +378,7 @@ impl RefFromWasmAbi for str { impl IntoWasmAbi for JsValue { type Abi = u32; + #[inline] fn into_abi(self, _extra: &mut Stack) -> u32 { let ret = self.idx; mem::forget(self); @@ -359,6 +389,7 @@ impl IntoWasmAbi for JsValue { impl FromWasmAbi for JsValue { type Abi = u32; + #[inline] unsafe fn from_abi(js: u32, _extra: &mut Stack) -> JsValue { JsValue { idx: js } } @@ -366,6 +397,8 @@ impl FromWasmAbi for JsValue { impl<'a> IntoWasmAbi for &'a JsValue { type Abi = u32; + + #[inline] fn into_abi(self, _extra: &mut Stack) -> u32 { self.idx } @@ -375,6 +408,7 @@ impl RefFromWasmAbi for JsValue { type Abi = u32; type Anchor = ManuallyDrop; + #[inline] unsafe fn ref_from_abi(js: u32, _extra: &mut Stack) -> Self::Anchor { ManuallyDrop::new(JsValue { idx: js }) } @@ -384,6 +418,7 @@ if_std! { impl IntoWasmAbi for Box<[JsValue]> { type Abi = WasmSlice; + #[inline] fn into_abi(self, extra: &mut Stack) -> WasmSlice { let ptr = self.as_ptr(); let len = self.len(); @@ -398,6 +433,7 @@ if_std! { impl FromWasmAbi for Box<[JsValue]> { type Abi = WasmSlice; + #[inline] unsafe fn from_abi(js: WasmSlice, extra: &mut Stack) -> Self { let ptr = <*mut JsValue>::from_abi(js.ptr, extra); let len = js.len as usize; @@ -414,12 +450,14 @@ const GLOBAL_STACK_CAP: usize = 16; static mut GLOBAL_STACK: [u32; GLOBAL_STACK_CAP] = [0; GLOBAL_STACK_CAP]; impl GlobalStack { + #[inline] pub unsafe fn new() -> GlobalStack { GlobalStack { next: 0 } } } impl Stack for GlobalStack { + #[inline] fn push(&mut self, val: u32) { unsafe { assert!(self.next < GLOBAL_STACK_CAP); From d0068976f61ca99d77ad4643dd02a2a2cd2e8cc2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Jul 2018 10:10:00 -0700 Subject: [PATCH 12/20] Remove usage of the `try_reserve` nightly feature Now that `GlobalAlloc` is stable no need to use it! --- src/lib.rs | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a43a8d80..ee2d19c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ //! this crate and this crate also provides JS bindings through the `JsValue` //! interface. -#![feature(use_extern_macros, wasm_import_module, try_reserve, unsize)] +#![feature(use_extern_macros, wasm_import_module, unsize)] #![cfg_attr(feature = "js_globals", feature(proc_macro, wasm_custom_section))] #![no_std] @@ -661,24 +661,29 @@ pub mod __rt { } if_std! { - use std::prelude::v1::*; + use std::alloc::{System, GlobalAlloc, Layout}; + use std::mem; #[no_mangle] pub extern fn __wbindgen_malloc(size: usize) -> *mut u8 { - use core::mem; - - let mut ret = Vec::new(); - if ret.try_reserve_exact(size).is_err() { - super::throw("invalid malloc request"); + let align = mem::align_of::(); + if let Ok(layout) = Layout::from_size_align(size, align) { + unsafe { + let ptr = System.alloc(layout); + if !ptr.is_null() { + return ptr + } + } } - let ptr = ret.as_mut_ptr(); - mem::forget(ret); - return ptr + + super::throw("invalid malloc request"); } #[no_mangle] pub unsafe extern fn __wbindgen_free(ptr: *mut u8, size: usize) { - drop(Vec::::from_raw_parts(ptr, 0, size)); + let align = mem::align_of::(); + let layout = Layout::from_size_align_unchecked(size, align); + System.dealloc(ptr, layout); } } From 1007449a173857ab4417ea7047c12cf6b380d230 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Fri, 13 Jul 2018 19:11:06 +0200 Subject: [PATCH 13/20] Enable Headers interface part of fetch API (#463) --- crates/web-sys/tests/all/headers.rs | 33 +++++++++++++++++++ crates/web-sys/tests/all/main.rs | 1 + .../{available => enabled}/Headers.webidl | 0 3 files changed, 34 insertions(+) create mode 100644 crates/web-sys/tests/all/headers.rs rename crates/web-sys/webidls/{available => enabled}/Headers.webidl (100%) diff --git a/crates/web-sys/tests/all/headers.rs b/crates/web-sys/tests/all/headers.rs new file mode 100644 index 00000000..8431f4f4 --- /dev/null +++ b/crates/web-sys/tests/all/headers.rs @@ -0,0 +1,33 @@ +use super::websys_project; + +#[test] +fn headers() { + websys_project() + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section)] + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + extern crate web_sys; + + #[wasm_bindgen] + pub fn test_headers(_headers: &web_sys::Headers) { + // empty for now... + } + "#, + ) + .file( + "test.js", + r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let headers = new Headers({'Content-Type': 'text/plain'}); + wasm.test_headers(headers); + } + "#, + ) + .test(); +} diff --git a/crates/web-sys/tests/all/main.rs b/crates/web-sys/tests/all/main.rs index e0181c24..181a596e 100644 --- a/crates/web-sys/tests/all/main.rs +++ b/crates/web-sys/tests/all/main.rs @@ -2,6 +2,7 @@ extern crate wasm_bindgen_test_project_builder as project_builder; use project_builder::{project, Project}; mod event; +mod headers; mod response; fn websys_project() -> Project { diff --git a/crates/web-sys/webidls/available/Headers.webidl b/crates/web-sys/webidls/enabled/Headers.webidl similarity index 100% rename from crates/web-sys/webidls/available/Headers.webidl rename to crates/web-sys/webidls/enabled/Headers.webidl From 63598721cab3e27e4416d9c63d3cde1a6e6991e6 Mon Sep 17 00:00:00 2001 From: Julius Rakow Date: Fri, 13 Jul 2018 19:56:19 +0200 Subject: [PATCH 14/20] rustfmt --- crates/webidl/tests/all/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/webidl/tests/all/main.rs b/crates/webidl/tests/all/main.rs index 13a6f789..10518c13 100644 --- a/crates/webidl/tests/all/main.rs +++ b/crates/webidl/tests/all/main.rs @@ -1,6 +1,6 @@ extern crate wasm_bindgen_test_project_builder as project_builder; use project_builder::project; -mod simple; mod enums; +mod simple; mod throws; From 862e4c50f6853b36f761f79c4ffdd0d45535e6c7 Mon Sep 17 00:00:00 2001 From: Julius Rakow Date: Fri, 13 Jul 2018 04:16:19 +0200 Subject: [PATCH 15/20] backend: add const to ast --- crates/backend/src/ast.rs | 27 +++++++++++++++++++++ crates/backend/src/codegen.rs | 40 ++++++++++++++++++++++++++++++++ crates/backend/src/defined.rs | 10 ++++++++ crates/cli-support/src/js/mod.rs | 1 + crates/shared/src/lib.rs | 4 ++++ 5 files changed, 82 insertions(+) diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 2c3c9661..cfdc2367 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -42,6 +42,7 @@ pub enum ImportKind { Static(ImportStatic), Type(ImportType), Enum(ImportEnum), + Const(Const), } #[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] @@ -174,6 +175,24 @@ pub struct TypeAlias { pub src: syn::Type, } +#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] +pub struct Const { + pub vis: syn::Visibility, + pub name: Ident, + pub interface_name: Ident, + pub ty: syn::Type, + pub value: ConstValue, +} + +#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] +/// same as webidl::ast::ConstValue +pub enum ConstValue { + BooleanLiteral(bool), + FloatLiteral(f64), + IntegerLiteral(i64), + Null, +} + impl Program { pub(crate) fn shared(&self) -> shared::Program { shared::Program { @@ -293,6 +312,7 @@ impl ImportKind { ImportKind::Static(_) => false, ImportKind::Type(_) => false, ImportKind::Enum(_) => false, + ImportKind::Const(_) => false, } } @@ -302,6 +322,7 @@ impl ImportKind { ImportKind::Static(ref f) => shared::ImportKind::Static(f.shared()), ImportKind::Type(ref f) => shared::ImportKind::Type(f.shared()), ImportKind::Enum(ref f) => shared::ImportKind::Enum(f.shared()), + ImportKind::Const(ref f) => shared::ImportKind::Const(f.shared()), } } } @@ -404,3 +425,9 @@ impl StructField { } } } + +impl Const { + fn shared(&self) -> shared::Const { + shared::Const {} + } +} diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 1e3e69af..a83d1923 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -501,6 +501,7 @@ impl ToTokens for ast::ImportKind { ast::ImportKind::Static(ref s) => s.to_tokens(tokens), ast::ImportKind::Type(ref t) => t.to_tokens(tokens), ast::ImportKind::Enum(ref e) => e.to_tokens(tokens), + ast::ImportKind::Const(ref c) => c.to_tokens(tokens), } } } @@ -842,6 +843,7 @@ impl<'a> ToTokens for DescribeImport<'a> { ast::ImportKind::Static(_) => return, ast::ImportKind::Type(_) => return, ast::ImportKind::Enum(_) => return, + ast::ImportKind::Const(_) => return, }; let describe_name = format!("__wbindgen_describe_{}", f.shim); let describe_name = Ident::new(&describe_name, Span::call_site()); @@ -958,3 +960,41 @@ impl ToTokens for ast::TypeAlias { }).to_tokens(into); } } + +impl ToTokens for ast::Const { + fn to_tokens(&self, tokens: &mut TokenStream) { + use ast::ConstValue::*; + + let vis = &self.vis; + let name = &self.name; + let interface_name = &self.interface_name; + let ty = &self.ty; + + let value: TokenStream = match self.value { + BooleanLiteral(false) => quote!(false), + BooleanLiteral(true) => quote!(true), + // the actual type is unknown because of typedefs + // so we cannot use std::fxx::INFINITY + // but we can use type inference + FloatLiteral(f) if f.is_infinite() && f.is_sign_positive() => quote!(1.0 / 0.0), + FloatLiteral(f) if f.is_infinite() && f.is_sign_negative() => quote!(-1.0 / 0.0), + FloatLiteral(f) if f.is_nan() => quote!(0.0 / 0.0), + // again no suffix + // panics on +-inf, nan + FloatLiteral(f) => { + let f = Literal::f64_unsuffixed(f); + quote!(#f) + }, + IntegerLiteral(i) => { + let i = Literal::i64_unsuffixed(i); + quote!(#i) + }, + Null => unimplemented!(), + }; + (quote! { + impl #interface_name { + #vis const #name: #ty = #value; + } + }).to_tokens(tokens); + } +} diff --git a/crates/backend/src/defined.rs b/crates/backend/src/defined.rs index d775cb02..84eabe50 100644 --- a/crates/backend/src/defined.rs +++ b/crates/backend/src/defined.rs @@ -106,6 +106,7 @@ impl ImportedTypes for ast::ImportKind { ast::ImportKind::Function(fun) => fun.imported_types(f), ast::ImportKind::Type(ty) => ty.imported_types(f), ast::ImportKind::Enum(enm) => enm.imported_types(f), + ast::ImportKind::Const(c) => c.imported_types(f), } } } @@ -229,6 +230,15 @@ impl ImportedTypes for ast::TypeAlias { } } +impl ImportedTypes for ast::Const { + fn imported_types(&self, f: &mut F) + where + F: FnMut(&Ident, ImportedTypeKind), + { + self.ty.imported_types(f); + } +} + /// Remove any methods, statics, &c, that reference types that are *not* /// defined. pub trait RemoveUndefinedImports { diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index ef47aa55..b23fe264 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1757,6 +1757,7 @@ impl<'a, 'b> SubContext<'a, 'b> { } shared::ImportKind::Type(_) => {} shared::ImportKind::Enum(_) => {} + shared::ImportKind::Const(_) => {} } Ok(()) } diff --git a/crates/shared/src/lib.rs b/crates/shared/src/lib.rs index 8df1e534..8985733d 100644 --- a/crates/shared/src/lib.rs +++ b/crates/shared/src/lib.rs @@ -34,6 +34,7 @@ pub enum ImportKind { Static(ImportStatic), Type(ImportType), Enum(ImportEnum), + Const(Const) } #[derive(Deserialize, Serialize)] @@ -124,6 +125,9 @@ pub struct StructField { pub comments: Vec, } +#[derive(Deserialize, Serialize)] +pub struct Const {} + pub fn new_function(struct_name: &str) -> String { let mut name = format!("__wbg_"); name.extend(struct_name.chars().flat_map(|s| s.to_lowercase())); From e35129445debd9499b67a96034b8504f606df4be Mon Sep 17 00:00:00 2001 From: Julius Rakow Date: Fri, 13 Jul 2018 06:04:40 +0200 Subject: [PATCH 16/20] webidl: translate webidl const to backend const --- crates/webidl/src/lib.rs | 35 ++++++++++++++++++++++++++++++----- crates/webidl/src/util.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/crates/webidl/src/lib.rs b/crates/webidl/src/lib.rs index e54e08bb..13b51e9f 100644 --- a/crates/webidl/src/lib.rs +++ b/crates/webidl/src/lib.rs @@ -29,12 +29,12 @@ use std::path::Path; use backend::defined::{ImportedTypeDefinitions, RemoveUndefinedImports}; use backend::util::{ident_ty, rust_ident, wrap_import_function}; use failure::ResultExt; -use heck::CamelCase; +use heck::{CamelCase, ShoutySnakeCase}; use quote::ToTokens; use util::{ - create_basic_method, create_function, create_getter, create_setter, webidl_ty_to_syn_ty, - TypePosition, + create_basic_method, create_function, create_getter, create_setter, webidl_const_ty_to_syn_ty, + webidl_const_v_to_backend_const_v, webidl_ty_to_syn_ty, TypePosition, }; /// Either `Ok(t)` or `Err(failure::Error)`. @@ -297,9 +297,9 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::InterfaceMember { attr.webidl_parse(program, self_name) } webidl::ast::InterfaceMember::Operation(ref op) => op.webidl_parse(program, self_name), + webidl::ast::InterfaceMember::Const(ref c) => c.webidl_parse(program, self_name), // TODO - webidl::ast::InterfaceMember::Const(_) - | webidl::ast::InterfaceMember::Iterable(_) + webidl::ast::InterfaceMember::Iterable(_) | webidl::ast::InterfaceMember::Maplike(_) | webidl::ast::InterfaceMember::Setlike(_) => { warn!("Unsupported WebIDL interface member: {:?}", self); @@ -474,3 +474,28 @@ impl<'a> WebidlParse<()> for webidl::ast::Enum { Ok(()) } } + +impl<'a> WebidlParse<&'a str> for webidl::ast::Const { + fn webidl_parse( + &self, + program: &mut backend::ast::Program, + interface_name: &'a str, + ) -> Result<()> { + let syn_ty = webidl_const_ty_to_syn_ty(&self.type_); + program.imports.push(backend::ast::Import { + module: None, + version: None, + js_namespace: None, + kind: backend::ast::ImportKind::Const(backend::ast::Const { + vis: syn::Visibility::Public(syn::VisPublic { + pub_token: Default::default(), + }), + name: rust_ident(self.name.to_shouty_snake_case().as_str()), + interface_name: rust_ident(interface_name), + ty: syn_ty, + value: webidl_const_v_to_backend_const_v(&self.value), + }), + }); + Ok(()) + } +} diff --git a/crates/webidl/src/util.rs b/crates/webidl/src/util.rs index b8edae82..042fba08 100644 --- a/crates/webidl/src/util.rs +++ b/crates/webidl/src/util.rs @@ -90,6 +90,35 @@ pub fn webidl_ty_to_syn_ty(ty: &webidl::ast::Type, pos: TypePosition) -> Option< }) } +pub fn webidl_const_ty_to_syn_ty(ty: &webidl::ast::ConstType) -> syn::Type { + use webidl::ast::ConstType::*; + + // similar to webidl_ty_to_syn_ty + match ty { + Boolean => ident_ty(raw_ident("bool")), + Byte => ident_ty(raw_ident("i8")), + Octet => ident_ty(raw_ident("u8")), + RestrictedDouble | UnrestrictedDouble => ident_ty(raw_ident("f64")), + RestrictedFloat | UnrestrictedFloat => ident_ty(raw_ident("f32")), + SignedLong => ident_ty(raw_ident("i32")), + SignedLongLong => ident_ty(raw_ident("i64")), + SignedShort => ident_ty(raw_ident("i16")), + UnsignedLong => ident_ty(raw_ident("u32")), + UnsignedLongLong => ident_ty(raw_ident("u64")), + UnsignedShort => ident_ty(raw_ident("u16")), + Identifier(ref id) => ident_ty(rust_ident(id)), + } +} + +pub fn webidl_const_v_to_backend_const_v(v: &webidl::ast::ConstValue) -> backend::ast::ConstValue { + match *v { + webidl::ast::ConstValue::BooleanLiteral(b) => backend::ast::ConstValue::BooleanLiteral(b), + webidl::ast::ConstValue::FloatLiteral(f) => backend::ast::ConstValue::FloatLiteral(f), + webidl::ast::ConstValue::IntegerLiteral(i) => backend::ast::ConstValue::IntegerLiteral(i), + webidl::ast::ConstValue::Null => backend::ast::ConstValue::Null, + } +} + fn simple_fn_arg(ident: Ident, ty: syn::Type) -> syn::ArgCaptured { syn::ArgCaptured { pat: syn::Pat::Ident(syn::PatIdent { From b23b9cce5b98148d903410b8deff2d71b5db5d0c Mon Sep 17 00:00:00 2001 From: Julius Rakow Date: Fri, 13 Jul 2018 18:32:04 +0200 Subject: [PATCH 17/20] webidl: add empty constant test file --- crates/webidl/tests/all/consts.rs | 1 + crates/webidl/tests/all/main.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 crates/webidl/tests/all/consts.rs diff --git a/crates/webidl/tests/all/consts.rs b/crates/webidl/tests/all/consts.rs new file mode 100644 index 00000000..162c6b3f --- /dev/null +++ b/crates/webidl/tests/all/consts.rs @@ -0,0 +1 @@ +use super::project; diff --git a/crates/webidl/tests/all/main.rs b/crates/webidl/tests/all/main.rs index 10518c13..3815c632 100644 --- a/crates/webidl/tests/all/main.rs +++ b/crates/webidl/tests/all/main.rs @@ -1,6 +1,7 @@ extern crate wasm_bindgen_test_project_builder as project_builder; use project_builder::project; +mod consts; mod enums; mod simple; mod throws; From 88f0e84f6cbe1ba7a1be52431179e77e39983e33 Mon Sep 17 00:00:00 2001 From: Julius Rakow Date: Fri, 13 Jul 2018 18:32:04 +0200 Subject: [PATCH 18/20] webidl: add bool const test --- crates/webidl/tests/all/consts.rs | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/crates/webidl/tests/all/consts.rs b/crates/webidl/tests/all/consts.rs index 162c6b3f..dc019eb7 100644 --- a/crates/webidl/tests/all/consts.rs +++ b/crates/webidl/tests/all/consts.rs @@ -1 +1,44 @@ use super::project; + +#[test] +fn bool() { + project() + .file( + "foo.webidl", + r#" + interface Foo { + const boolean not_true = false; + const boolean not_false = true; + }; + "#, + ) + // a corresponding const in the js implementation is not required + // value is taken directly from idl + .file( + "foo.js", + r#" + export class Foo { + } + "#, + ) + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section, wasm_import_module)] + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + + pub mod foo; + use foo::Foo; + + #[wasm_bindgen] + pub fn test() { + let falsish: bool = Foo::NOT_TRUE; + assert!(!falsish); + let trueish: bool = Foo::NOT_FALSE; + assert!(trueish); + } + "#, + ) + .test(); +} From 473ac6d2eee2f700d96ceddf718f4982c8e92bcb Mon Sep 17 00:00:00 2001 From: Julius Rakow Date: Fri, 13 Jul 2018 19:08:14 +0200 Subject: [PATCH 19/20] webidl: add int const test --- crates/webidl/tests/all/consts.rs | 85 +++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/crates/webidl/tests/all/consts.rs b/crates/webidl/tests/all/consts.rs index dc019eb7..a187c516 100644 --- a/crates/webidl/tests/all/consts.rs +++ b/crates/webidl/tests/all/consts.rs @@ -42,3 +42,88 @@ fn bool() { ) .test(); } + +#[test] +fn ints() { + project() + .file( + "foo.webidl", + r#" + interface Byte { + const byte imin = -128; + const byte imax = 127; + const octet umin = 0; + const octet umax = 255; + }; + interface Short { + const short imin = -32768; + const short imax = 32767; + const unsigned short umin = 0; + const unsigned short umax = 65535; + }; + interface Long { + const long imin = -2147483648; + const long imax = 2147483647; + const unsigned long umin = 0; + const unsigned long umax = 4294967295; + }; + interface LongLong { + const long long imin = -9223372036854775808; + const long long imax = 9223372036854775807; + const unsigned long long umin = 0; + // bug in webidl + // https://github.com/sgodwincs/webidl-rs/issues/15 + //const unsigned long long umax = 18446744073709551615; + }; + "#, + ) + // a corresponding const in the js implementation is not required + // value is taken directly from idl + .file( + "foo.js", + r#" + export class Byte { + } + export class Short { + } + export class Long { + } + export class LongLong { + } + "#, + ) + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section, wasm_import_module)] + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + + pub mod foo; + + #[wasm_bindgen] + pub fn test() { + assert_eq!(foo::Byte::IMIN, i8::min_value()); + assert_eq!(foo::Byte::IMAX, i8::max_value()); + assert_eq!(foo::Byte::UMIN, u8::min_value()); + assert_eq!(foo::Byte::UMAX, u8::max_value()); + + assert_eq!(foo::Short::IMIN, i16::min_value()); + assert_eq!(foo::Short::IMAX, i16::max_value()); + assert_eq!(foo::Short::UMIN, u16::min_value()); + assert_eq!(foo::Short::UMAX, u16::max_value()); + + assert_eq!(foo::Long::IMIN, i32::min_value()); + assert_eq!(foo::Long::IMAX, i32::max_value()); + assert_eq!(foo::Long::UMIN, u32::min_value()); + assert_eq!(foo::Long::UMAX, u32::max_value()); + + assert_eq!(foo::LongLong::IMIN, i64::min_value()); + assert_eq!(foo::LongLong::IMAX, i64::max_value()); + assert_eq!(foo::LongLong::UMIN, u64::min_value()); + //assert_eq!(foo::LongLong::UMAX, u64::max_value()); + } + "#, + ) + .test(); +} From 9ebd8bc790af33872e02c6c7903f0507bf71f2d9 Mon Sep 17 00:00:00 2001 From: Julius Rakow Date: Fri, 13 Jul 2018 19:51:11 +0200 Subject: [PATCH 20/20] webidl: add float const test --- crates/webidl/tests/all/consts.rs | 61 +++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/crates/webidl/tests/all/consts.rs b/crates/webidl/tests/all/consts.rs index a187c516..dd2265e0 100644 --- a/crates/webidl/tests/all/consts.rs +++ b/crates/webidl/tests/all/consts.rs @@ -127,3 +127,64 @@ fn ints() { ) .test(); } + +#[test] +fn floats() { + project() + .file( + "foo.webidl", + r#" + interface floats { + const float f = 0.0; + const unrestricted float neg_inf = -Infinity; + const unrestricted float inf = Infinity; + const unrestricted float nan = NaN; + }; + interface doubles { + const double d = 0.0; + const unrestricted double neg_inf = -Infinity; + const unrestricted double inf = Infinity; + const unrestricted double nan = NaN; + }; + "#, + ) + // a corresponding const in the js implementation is not required + // value is taken directly from idl + .file( + "foo.js", + r#" + export class floats { + } + export class doubles { + } + "#, + ) + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section, wasm_import_module)] + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + + pub mod foo; + + #[wasm_bindgen] + pub fn test() { + assert_eq!(foo::floats::F, 0.0); + assert!(foo::floats::NEG_INF.is_infinite()); + assert!(foo::floats::NEG_INF.is_sign_negative()); + assert!(foo::floats::INF.is_infinite()); + assert!(foo::floats::INF.is_sign_positive()); + assert!(foo::floats::NAN.is_nan()); + + assert_eq!(foo::doubles::D, 0.0); + assert!(foo::doubles::NEG_INF.is_infinite()); + assert!(foo::doubles::NEG_INF.is_sign_negative()); + assert!(foo::doubles::INF.is_infinite()); + assert!(foo::doubles::INF.is_sign_positive()); + assert!(foo::doubles::NAN.is_nan()); + } + "#, + ) + .test(); +}