Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 27 additions & 23 deletions core/engine/src/object/builtins/jsarray.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! A Rust API wrapper for Boa's `Array` Builtin ECMAScript Object
use crate::{
Context, JsResult, JsString, JsValue,
Context, JsExpect, JsResult, JsString, JsValue,
builtins::Array,
error::JsNativeError,
object::{JsFunction, JsObject},
Expand All @@ -17,12 +17,16 @@ pub struct JsArray {

impl JsArray {
/// Create a new empty array.
///
/// # Errors
///
/// Returns a `PanicError` if creating the array fails due to an engine bug.
#[inline]
pub fn new(context: &mut Context) -> Self {
pub fn new(context: &mut Context) -> JsResult<Self> {
let inner = Array::array_create(0, None, context)
.expect("creating an empty array with the default prototype must not fail");
.js_expect("creating an empty array with the default prototype must not fail")?;

Self { inner }
Ok(Self { inner })
}

/// Create an array from a `IntoIterator<Item = JsValue>` convertible object.
Expand Down Expand Up @@ -115,23 +119,23 @@ impl JsArray {
pub fn concat(&self, items: &[JsValue], context: &mut Context) -> JsResult<Self> {
let object = Array::concat(&self.inner.clone().into(), items, context)?
.as_object()
.expect("Array.prototype.filter should always return object");
.js_expect("Array.prototype.concat should always return object")?;

Self::from_object(object)
}

/// Calls `Array.prototype.join()`.
#[inline]
pub fn join(&self, separator: Option<JsString>, context: &mut Context) -> JsResult<JsString> {
Array::join(
let result = Array::join(
&self.inner.clone().into(),
&[separator.into_or_undefined()],
context,
)
.map(|x| {
x.as_string()
.expect("Array.prototype.join always returns string")
})
)?;
result
.as_string()
.js_expect("Array.prototype.join always returns string")
.map_err(Into::into)
}

/// Calls `Array.prototype.fill()`.
Expand Down Expand Up @@ -173,7 +177,7 @@ impl JsArray {
context,
)?
.as_number()
.expect("Array.prototype.indexOf should always return number");
.js_expect("Array.prototype.indexOf should always return number")?;

#[allow(clippy::float_cmp)]
if index == -1.0 {
Expand All @@ -199,7 +203,7 @@ impl JsArray {
context,
)?
.as_number()
.expect("Array.prototype.lastIndexOf should always return number");
.js_expect("Array.prototype.lastIndexOf should always return number")?;

#[allow(clippy::float_cmp)]
if index == -1.0 {
Expand Down Expand Up @@ -238,7 +242,7 @@ impl JsArray {
context,
)?
.as_object()
.expect("Array.prototype.filter should always return object");
.js_expect("Array.prototype.filter should always return object")?;

Self::from_object(object)
}
Expand All @@ -257,7 +261,7 @@ impl JsArray {
context,
)?
.as_object()
.expect("Array.prototype.map should always return object");
.js_expect("Array.prototype.map should always return object")?;

Self::from_object(object)
}
Expand All @@ -276,7 +280,7 @@ impl JsArray {
context,
)?
.as_boolean()
.expect("Array.prototype.every should always return boolean");
.js_expect("Array.prototype.every should always return boolean")?;

Ok(result)
}
Expand All @@ -295,7 +299,7 @@ impl JsArray {
context,
)?
.as_boolean()
.expect("Array.prototype.some should always return boolean");
.js_expect("Array.prototype.some should always return boolean")?;

Ok(result)
}
Expand Down Expand Up @@ -326,7 +330,7 @@ impl JsArray {
context,
)?
.as_object()
.expect("Array.prototype.slice should always return object");
.js_expect("Array.prototype.slice should always return object")?;

Self::from_object(object)
}
Expand Down Expand Up @@ -378,7 +382,7 @@ impl JsArray {
context,
)?
.as_object()
.expect("Array.prototype.splice should always return object");
.js_expect("Array.prototype.splice should always return object")?;

Self::from_object(object)
}
Expand Down Expand Up @@ -421,7 +425,7 @@ impl JsArray {
Ok(Self {
inner: array
.as_object()
.expect("`to_reversed` must always return an `Array` on success"),
.js_expect("`to_reversed` must always return an `Array` on success")?,
})
}

Expand All @@ -441,7 +445,7 @@ impl JsArray {
Ok(Self {
inner: array
.as_object()
.expect("`to_sorted` must always return an `Array` on success"),
.js_expect("`to_sorted` must always return an `Array` on success")?,
})
}

Expand All @@ -453,7 +457,7 @@ impl JsArray {
Ok(Self {
inner: array
.as_object()
.expect("`with` must always return an `Array` on success"),
.js_expect("`with` must always return an `Array` on success")?,
})
}
}
Expand Down Expand Up @@ -547,7 +551,7 @@ mod tests {
#[test]
fn splice_empty_array() {
let context = &mut Context::default();
let array = JsArray::new(context);
let array = JsArray::new(context).unwrap();

let removed = array.splice(0, Some(0), &[], context).unwrap();

Expand Down
9 changes: 6 additions & 3 deletions core/engine/src/object/builtins/jsmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use std::ops::Deref;
/// let context = &mut Context::default();
///
/// // Create an array of two `[key, value]` pairs
/// let js_array = JsArray::new(context);
/// let js_array = JsArray::new(context)?;
///
/// // Create a `[key, value]` pair of JsValues
/// let vec_one: Vec<JsValue> = vec![
Expand Down Expand Up @@ -111,7 +111,7 @@ impl JsMap {
/// # // Create a default `Context`
/// # let context = &mut Context::default();
/// // Create an array of two `[key, value]` pairs
/// let js_array = JsArray::new(context);
/// let js_array = JsArray::new(context)?;
///
/// // Create a `[key, value]` pair of JsValues and add it to the `JsArray` as a `JsArray`
/// let vec_one: Vec<JsValue> = vec![js_string!("first-key").into(), js_string!("first-value").into()];
Expand Down Expand Up @@ -171,11 +171,14 @@ impl JsMap {
/// # object::{JsObject, builtins::{JsArray, JsMap}},
/// # Context, JsResult, JsValue,
/// # };
/// # fn main() -> JsResult<()> {
/// # let context = &mut Context::default();
/// let some_object = JsArray::new(context);
/// let some_object = JsArray::new(context)?;
///
/// // `some_object` is an Array object, not a map object
/// assert!(JsMap::from_object(some_object.into()).is_err());
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn from_object(object: JsObject) -> JsResult<Self> {
Expand Down
7 changes: 5 additions & 2 deletions core/engine/src/object/jsobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,17 +436,20 @@ impl JsObject {
/// # Examples
///
/// ```
/// # use boa_engine::{Context, JsObject, JsValue};
/// # use boa_engine::{Context, JsObject, JsValue ,JsResult};
/// # use boa_engine::object::builtins::JsArray;
/// # fn main() -> JsResult<()> {
/// let context = &mut Context::default();
///
/// let array = JsArray::new(context);
/// let array = JsArray::new(context)?;
/// // A JsArray's inner JsObject is an array.
/// assert!(JsObject::from(array).is_array());
///
/// // An ordinary object is not an array.
/// let obj = JsObject::with_object_proto(context.intrinsics());
/// assert!(!obj.is_array());
/// # Ok(())
/// # }
/// ```
#[inline]
#[must_use]
Expand Down
2 changes: 1 addition & 1 deletion core/engine/src/value/conversions/serde_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ mod tests {
.create_data_property(js_string!("inner_a"), JsValue::undefined(), &mut context)
.expect("should add property");

let array = JsArray::new(&mut context);
let array = JsArray::new(&mut context).expect("creating array in test must not fail");
array.push(2, &mut context).expect("should push");
array
.push(JsValue::undefined(), &mut context)
Expand Down
4 changes: 2 additions & 2 deletions core/engine/src/value/conversions/try_into_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ where
T: TryIntoJs,
{
fn try_into_js(&self, context: &mut Context) -> JsResult<JsValue> {
let arr = crate::object::JsArray::new(context);
let arr = crate::object::JsArray::new(context)?;
for value in self {
let value = value.try_into_js(context)?;
arr.push(value, context)?;
Expand All @@ -177,7 +177,7 @@ macro_rules! impl_try_into_js_for_tuples {
impl<$($ts: TryIntoJs,)+> TryIntoJs for ($($ts,)+) {
fn try_into_js(&self, context: &mut Context) -> JsResult<JsValue> {
let ($($names,)+) = self;
let arr = crate::object::JsArray::new(context);
let arr = crate::object::JsArray::new(context)?;
$(arr.push($names.try_into_js(context)?, context)?;)+
Ok(arr.into())
}
Expand Down
2 changes: 1 addition & 1 deletion core/runtime/src/store/to.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn try_items_into_js_array(
seen: &mut ReverseSeenMap,
context: &mut Context,
) -> JsResult<JsValue> {
let dolly = JsArray::new(context);
let dolly = JsArray::new(context)?;
seen.insert(store, dolly.clone().into());

for (k, v) in items
Expand Down
2 changes: 1 addition & 1 deletion examples/src/bin/jsarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn main() -> JsResult<()> {
let context = &mut Context::default();

// Create an empty array.
let array = JsArray::new(context);
let array = JsArray::new(context)?;

assert!(array.is_empty(context)?);

Expand Down
2 changes: 1 addition & 1 deletion examples/src/bin/jsmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn main() -> JsResult<()> {
let _first_value = entries.next(context)?;

// Create a multidimensional array with key value pairs -> [[first-key, first-value], [second-key, second-value]]
let js_array = JsArray::new(context);
let js_array = JsArray::new(context)?;

let vec_one = vec![
JsValue::new(js_string!("first-key")),
Expand Down
Loading