Skip to content

Commit

Permalink
Add an "iter()" method to Js*Array for convenience (boa-dev#3986)
Browse files Browse the repository at this point in the history
* Allow dead code for code that is newly detected as unused

* Fix compile errors with nightly rust

* Add missing SAFETY section

* Increase safety of `FutexWaiters`

* Add an "iter()" method to Js*Array for convenience

It might be optimizable, and in either case it should be but this at
least let people use an easy API and enjoy future improvements.

* Fix clippies

---------

Co-authored-by: Theo Paris <[email protected]>
Co-authored-by: José Julián Espina <[email protected]>
  • Loading branch information
3 people committed Sep 12, 2024
1 parent c61cd91 commit 0c8cef3
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
56 changes: 55 additions & 1 deletion core/engine/src/object/builtins/jstypedarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ impl JsTypedArray {

/// Iterates the typed array in reverse order and returns the value of
/// the first element that satisfies the provided testing function.
/// If no elements satisfy the testing function, `JsResult::Ok(None)` is returned.
/// If no elements satisfy the testing function, `JsResult::Ok(None)` is returned.
///
/// Calls `TypedArray.prototype.findLast()`.
///
Expand Down Expand Up @@ -927,6 +927,7 @@ macro_rules! JsTypedArrayType {
$constructor_function:ident,
$checker_function:ident,
$constructor_object:ident,
$value_to_elem:ident,
$element:ty
) => {

Expand Down Expand Up @@ -1017,6 +1018,21 @@ macro_rules! JsTypedArrayType {
},
})
}

/// Create an iterator over the typed array's elements.
pub fn iter<'a>(&'a self, context: &'a mut Context) -> impl Iterator<Item = $element> + 'a {
let length = self.length(context).unwrap_or(0);
let mut index = 0;
std::iter::from_fn(move || {
if index < length {
let value = self.get(index, context).ok()?;
index += 1;
value.$value_to_elem(context).ok()
} else {
None
}
})
}
}

impl From<$name> for JsObject {
Expand Down Expand Up @@ -1066,54 +1082,92 @@ JsTypedArrayType!(
Uint8Array,
is_typed_uint8_array,
typed_uint8_array,
to_uint8,
u8
);
JsTypedArrayType!(
JsInt8Array,
Int8Array,
is_typed_int8_array,
typed_int8_array,
to_int8,
i8
);
JsTypedArrayType!(
JsUint16Array,
Uint16Array,
is_typed_uint16_array,
typed_uint16_array,
to_uint16,
u16
);
JsTypedArrayType!(
JsInt16Array,
Int16Array,
is_typed_int16_array,
typed_int16_array,
to_int16,
i16
);
JsTypedArrayType!(
JsUint32Array,
Uint32Array,
is_typed_uint32_array,
typed_uint32_array,
to_u32,
u32
);
JsTypedArrayType!(
JsInt32Array,
Int32Array,
is_typed_int32_array,
typed_int32_array,
to_i32,
i32
);
JsTypedArrayType!(
JsFloat32Array,
Float32Array,
is_typed_float32_array,
typed_float32_array,
to_f32,
f32
);
JsTypedArrayType!(
JsFloat64Array,
Float64Array,
is_typed_float64_array,
typed_float64_array,
to_number,
f64
);

#[test]
fn typed_iterators_uint8() {
let context = &mut Context::default();
let vec = vec![1u8, 2, 3, 4, 5, 6, 7, 8];

let array = JsUint8Array::from_iter(vec.clone(), context).unwrap();
let vec2 = array.iter(context).collect::<Vec<_>>();
assert_eq!(vec, vec2);
}

#[test]
fn typed_iterators_uint32() {
let context = &mut Context::default();
let vec = vec![1u32, 2, 0xFFFF, 4, 0xFF12_3456, 6, 7, 8];

let array = JsUint32Array::from_iter(vec.clone(), context).unwrap();
let vec2 = array.iter(context).collect::<Vec<_>>();
assert_eq!(vec, vec2);
}

#[test]
fn typed_iterators_f32() {
let context = &mut Context::default();
let vec = vec![0.1f32, 0.2, 0.3, 0.4, 1.1, 9.99999];

let array = JsFloat32Array::from_iter(vec.clone(), context).unwrap();
let vec2 = array.iter(context).collect::<Vec<_>>();
assert_eq!(vec, vec2);
}
5 changes: 5 additions & 0 deletions core/engine/src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,11 @@ impl JsValue {
}
}

/// Converts a value to a 32 bit floating point.
pub fn to_f32(&self, context: &mut Context) -> JsResult<f32> {
self.to_number(context).map(|n| n as f32)
}

/// This is a more specialized version of `to_numeric`, including `BigInt`.
///
/// This function is equivalent to `Number(value)` in JavaScript
Expand Down

0 comments on commit 0c8cef3

Please sign in to comment.