Skip to content

Commit d51f539

Browse files
lshlyapnikovalexcrichton
authored andcommitted
Add an unsafe method view_mut_raw (#1850)
* adding .vscode folder to .gitignore * Adding view_mut_raw to generated arrays * test populating rust vector from JS function * Uint32Array test, need to make it generic * Add doc + more test cases * replacing macro-generated tests with generic test function it is cleaner, safer and better that way * improving rustdoc
1 parent e7bfa16 commit d51f539

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ yarn.lock
99
*.d.ts
1010
/publish
1111
/publish.exe
12+
.vscode

crates/js-sys/src/lib.rs

+25
Original file line numberDiff line numberDiff line change
@@ -4792,6 +4792,31 @@ macro_rules! arrays {
47924792
)
47934793
}
47944794

4795+
/// Creates a JS typed array which is a view into wasm's linear
4796+
/// memory at the specified pointer with specified length.
4797+
///
4798+
/// This function returns a new typed array which is a view into
4799+
/// wasm's memory. This view does not copy the underlying data.
4800+
///
4801+
/// # Unsafety
4802+
///
4803+
/// Views into WebAssembly memory are only valid so long as the
4804+
/// backing buffer isn't resized in JS. Once this function is called
4805+
/// any future calls to `Box::new` (or malloc of any form) may cause
4806+
/// the returned value here to be invalidated. Use with caution!
4807+
///
4808+
/// Additionally the returned object can be safely mutated,
4809+
/// the changes are guranteed to be reflected in the input array.
4810+
pub unsafe fn view_mut_raw(ptr: *mut $ty, length: usize) -> $name {
4811+
let buf = wasm_bindgen::memory();
4812+
let mem = buf.unchecked_ref::<WebAssembly::Memory>();
4813+
$name::new_with_byte_offset_and_length(
4814+
&mem.buffer(),
4815+
ptr as u32,
4816+
length as u32
4817+
)
4818+
}
4819+
47954820
fn raw_copy_to(&self, dst: &mut [$ty]) {
47964821
let buf = wasm_bindgen::memory();
47974822
let mem = buf.unchecked_ref::<WebAssembly::Memory>();

crates/js-sys/tests/wasm/Array.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Used for `Array.rs` tests
2+
exports.populate_array = function(arr, start, len) {
3+
for (i = 0; i < len; i++) {
4+
arr[i] = start + i;
5+
}
6+
};

crates/js-sys/tests/wasm/Array.rs

+85
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use js_sys::*;
22
use std::iter::FromIterator;
3+
use wasm_bindgen::prelude::*;
34
use wasm_bindgen::JsCast;
45
use wasm_bindgen::JsValue;
56
use wasm_bindgen_test::*;
@@ -466,3 +467,87 @@ fn array_inheritance() {
466467
assert!(array.is_instance_of::<Object>());
467468
let _: &Object = array.as_ref();
468469
}
470+
471+
#[wasm_bindgen(module = "tests/wasm/Array.js")]
472+
extern "C" {
473+
fn populate_array(arr: JsValue, start: JsValue, len: JsValue) -> JsValue;
474+
}
475+
476+
fn test_array_view_mut_raw<ElemT: std::cmp::PartialEq + std::fmt::Debug, ArrT>(
477+
sut: unsafe fn(*mut ElemT, usize) -> ArrT,
478+
u8ToElem: fn(u8) -> ElemT,
479+
arrToJsValue: fn(ArrT) -> JsValue,
480+
) {
481+
let start: u8 = 10;
482+
let len: usize = 32;
483+
let end: u8 = start + len as u8;
484+
let mut buffer: Vec<ElemT> = Vec::new();
485+
buffer.reserve(len);
486+
unsafe {
487+
let array: ArrT = sut(buffer.as_mut_ptr(), len);
488+
populate_array(
489+
arrToJsValue(array),
490+
JsValue::from(start),
491+
JsValue::from(len as u32),
492+
);
493+
buffer.set_len(len);
494+
}
495+
let expected: Vec<ElemT> = (start..end).map(u8ToElem).collect();
496+
assert_eq!(buffer, expected)
497+
}
498+
499+
#[wasm_bindgen_test]
500+
fn Int8Array_view_mut_raw() {
501+
fn u8Toi8_unsafe(x: u8) -> i8 {
502+
x as i8
503+
}
504+
test_array_view_mut_raw(
505+
js_sys::Int8Array::view_mut_raw,
506+
u8Toi8_unsafe,
507+
JsValue::from,
508+
);
509+
}
510+
511+
#[wasm_bindgen_test]
512+
fn Int16Array_view_mut_raw() {
513+
test_array_view_mut_raw(js_sys::Int16Array::view_mut_raw, i16::from, JsValue::from);
514+
}
515+
516+
#[wasm_bindgen_test]
517+
fn Int32Array_view_mut_raw() {
518+
test_array_view_mut_raw(js_sys::Int32Array::view_mut_raw, i32::from, JsValue::from);
519+
}
520+
521+
#[wasm_bindgen_test]
522+
fn Uint8Array_view_mut_raw() {
523+
test_array_view_mut_raw(js_sys::Uint8Array::view_mut_raw, u8::from, JsValue::from);
524+
}
525+
526+
#[wasm_bindgen_test]
527+
fn Uint8ClampedArray_view_mut_raw() {
528+
test_array_view_mut_raw(
529+
js_sys::Uint8ClampedArray::view_mut_raw,
530+
u8::from,
531+
JsValue::from,
532+
);
533+
}
534+
535+
#[wasm_bindgen_test]
536+
fn Uint16Array_view_mut_raw() {
537+
test_array_view_mut_raw(js_sys::Uint16Array::view_mut_raw, u16::from, JsValue::from);
538+
}
539+
540+
#[wasm_bindgen_test]
541+
fn Uint32Array_view_mut_raw() {
542+
test_array_view_mut_raw(js_sys::Uint32Array::view_mut_raw, u32::from, JsValue::from);
543+
}
544+
545+
#[wasm_bindgen_test]
546+
fn Float32Array_view_mut_raw() {
547+
test_array_view_mut_raw(js_sys::Float32Array::view_mut_raw, f32::from, JsValue::from);
548+
}
549+
550+
#[wasm_bindgen_test]
551+
fn Float64Array_view_mut_raw() {
552+
test_array_view_mut_raw(js_sys::Float64Array::view_mut_raw, f64::from, JsValue::from);
553+
}

0 commit comments

Comments
 (0)