Skip to content

Commit

Permalink
Safe wrapper for JsSet (#2162)
Browse files Browse the repository at this point in the history
This PR adds a safe wrapper around JavaScript `JsSet` from `builtins::set`, and is being tracked at #2098.

Implements following methods 
- [x] `Set.prototype.size`
- [x] `Set.prototype.add(value)`
- [x] `Set.prototype.clear()`
- [x] `Set.prototype.delete(value)`
- [x] `Set.prototype.has(value)`
- [x] `Set.prototype.forEach(callbackFn[, thisArg])`
Implement wrapper for `builtins::set_iterator`, to be used by following.
- [x] `Set.prototype.values()`
- [x] `Set.prototype.keys()`
- [x] `Set.prototype.entries()`


*Note: Are there any other functions that should be added?

Also adds `set_create()` and made `get_size()` public in `builtins::set`.
  • Loading branch information
lameferret committed Jul 7, 2022
1 parent d7fb049 commit 52bc15b
Show file tree
Hide file tree
Showing 32 changed files with 403 additions and 46 deletions.
2 changes: 1 addition & 1 deletion boa_engine/src/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl JsBigInt {
})
}

/// This function takes a string and conversts it to `BigInt` type.
/// This function takes a string and converts it to `BigInt` type.
///
/// More information:
/// - [ECMAScript reference][spec]
Expand Down
10 changes: 5 additions & 5 deletions boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,8 +949,8 @@ impl Array {
while lower != middle {
// a. Let upper be len - lower - 1.
let upper = len - lower - 1;
// Skiped: b. Let upperP be ! ToString(𝔽(upper)).
// Skiped: c. Let lowerP be ! ToString(𝔽(lower)).
// Skipped: b. Let upperP be ! ToString(𝔽(upper)).
// Skipped: c. Let lowerP be ! ToString(𝔽(lower)).
// d. Let lowerExists be ? HasProperty(O, lowerP).
let lower_exists = o.has_property(lower, context)?;
// e. If lowerExists is true, then
Expand Down Expand Up @@ -2369,7 +2369,7 @@ impl Array {
// 10. If ySmaller is true, return 1𝔽.
// 11. Return +0𝔽.

// NOTE: skipped IsLessThan because it just makes a lexicographic comparation
// NOTE: skipped IsLessThan because it just makes a lexicographic comparison
// when x and y are strings
Ok(x_str.cmp(&y_str))
};
Expand Down Expand Up @@ -2808,7 +2808,7 @@ impl Array {
// 4. Else, let k be min(relativeStart, len).
IntegerOrInfinity::Integer(i) => Ok(min(i, len as i64) as usize),

// Special case - postive infinity. `len` is always smaller than +inf, thus from (4)
// Special case - positive infinity. `len` is always smaller than +inf, thus from (4)
IntegerOrInfinity::PositiveInfinity => Ok(len),
}
}
Expand Down Expand Up @@ -2836,7 +2836,7 @@ impl Array {
// Both `as` casts are safe as both variables are non-negative
IntegerOrInfinity::Integer(i) => Ok(min(i, len as i64) as usize),

// Special case - postive infinity. `len` is always smaller than +inf, thus from (4)
// Special case - positive infinity. `len` is always smaller than +inf, thus from (4)
IntegerOrInfinity::PositiveInfinity => Ok(len),
}
}
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/array_buffer/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::*;

#[test]
fn ut_sunnyy_day_create_byte_data_block() {
fn ut_sunny_day_create_byte_data_block() {
let mut context = Context::default();

assert!(create_byte_data_block(100, &mut context).is_ok());
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/builtins/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,12 @@ impl Date {
let duration_hour = Duration::milliseconds(hour.checked_mul(MILLIS_PER_HOUR)?);
let duration_minute = Duration::milliseconds(minute.checked_mul(MILLIS_PER_MINUTE)?);
let duration_second = Duration::milliseconds(second.checked_mul(MILLIS_PER_SECOND)?);
let duration_milisecond = Duration::milliseconds(millisecond);
let duration_millisecond = Duration::milliseconds(millisecond);

let duration = duration_hour
.checked_add(&duration_minute)?
.checked_add(&duration_second)?
.checked_add(&duration_milisecond)?;
.checked_add(&duration_millisecond)?;

NaiveDate::from_ymd_opt(year, month + 1, day + 1)
.and_then(|dt| dt.and_hms(0, 0, 0).checked_add_signed(duration))
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/error/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use tap::{Conv, Pipe};

use super::Error;

/// JavaScript `EvalError` impleentation.
/// JavaScript `EvalError` implementation.
#[derive(Debug, Clone, Copy)]
pub(crate) struct EvalError;

Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/error/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use tap::{Conv, Pipe};

use super::Error;

/// JavaScript `SyntaxError` impleentation.
/// JavaScript `SyntaxError` implementation.
#[derive(Debug, Clone, Copy)]
pub(crate) struct SyntaxError;

Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/error/uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use tap::{Conv, Pipe};

use super::Error;

/// JavaScript `URIError` impleentation.
/// JavaScript `URIError` implementation.
#[derive(Debug, Clone, Copy)]
pub(crate) struct UriError;

Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/intl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ pub(crate) fn default_number_option(

/// Abstract operation `CanonicalizeUnicodeLocaleId ( locale )`.
///
/// This function differs sligthly from the specification by modifying in-place
/// This function differs slightly from the specification by modifying in-place
/// the provided [`Locale`] instead of creating a new canonicalized copy.
///
/// More information:
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/json/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ fn json_stringify_array_converts_symbol_to_null() {
assert_eq!(actual, expected);
}
#[test]
fn json_stringify_function_replacer_propogate_error() {
fn json_stringify_function_replacer_propagate_error() {
let mut context = Context::default();

let actual = forward(
Expand Down
6 changes: 3 additions & 3 deletions boa_engine/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ impl Number {
/// represented by these digits is rounded using string
/// manipulation.
/// - Else, zeroes are appended to the string.
/// - Additionnally, sometimes the exponent was wrongly computed and
/// - Additionally, sometimes the exponent was wrongly computed and
/// while up-rounding we find that we need an extra digit. When this
/// happens, we return true so that the calling context can adjust
/// the exponent. The string is kept at an exact length of `precision`.
Expand All @@ -358,7 +358,7 @@ impl Number {
let to_round = digits.split_off(precision);
let mut digit = digits
.pop()
.expect("already checked that lenght is bigger than precision")
.expect("already checked that length is bigger than precision")
as u8;
if let Some(first) = to_round.chars().next() {
if first > '4' {
Expand Down Expand Up @@ -601,7 +601,7 @@ impl Number {
// Reconstruct digit.
let digit_0 = (c as char)
.to_digit(10)
.expect("charactre was not a valid digit");
.expect("character was not a valid digit");
if digit_0 + 1 >= u32::from(radix) {
continue;
}
Expand Down
31 changes: 28 additions & 3 deletions boa_engine/src/builtins/set/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! This module implements the global `Set` objest.
//! This module implements the global `Set` object.
//!
//! The JavaScript `Set` class is a global object that is used in the construction of sets; which
//! are high-level, collections of values.
Expand Down Expand Up @@ -164,6 +164,30 @@ impl Set {
Ok(set.into())
}

/// Utility for constructing `Set` objects.
pub(crate) fn set_create(prototype: Option<JsObject>, context: &mut Context) -> JsObject {
let prototype =
prototype.unwrap_or_else(|| context.intrinsics().constructors().set().prototype());

JsObject::from_proto_and_data(prototype, ObjectData::set(OrderedSet::new()))
}

/// Utility for constructing `Set` objects from an iterator of `JsValue`'s.
pub(crate) fn create_set_from_list<I>(elements: I, context: &mut Context) -> JsObject
where
I: IntoIterator<Item = JsValue>,
{
// Create empty Set
let set = Self::set_create(None, context);
// For each element e of elements, do
for elem in elements {
Self::add(&set.clone().into(), &[elem], context)
.expect("adding new element shouldn't error out");
}

set
}

/// `get Set [ @@species ]`
///
/// The Set[Symbol.species] accessor property returns the Set constructor.
Expand Down Expand Up @@ -323,6 +347,7 @@ impl Set {

let callback_arg = &args[0];
let this_arg = args.get_or_undefined(1);

// TODO: if condition should also check that we are not in strict mode
let this_arg = if this_arg.is_undefined() {
context.global_object().clone().into()
Expand Down Expand Up @@ -417,8 +442,8 @@ impl Set {
Self::get_size(this, context).map(JsValue::from)
}

/// Helper function to get the size of the set.
fn get_size(set: &JsValue, context: &mut Context) -> JsResult<usize> {
/// Helper function to get the size of the `Set` object.
pub(crate) fn get_size(set: &JsValue, context: &mut Context) -> JsResult<usize> {
set.as_object()
.and_then(|obj| obj.borrow().as_set_ref().map(OrderedSet::size))
.ok_or_else(|| context.construct_type_error("'this' is not a Set"))
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl String {

/// Abstract operation `thisStringValue( value )`
///
/// More informacion:
/// More information:
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#thisstringvalue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl IntegerIndexed {

/// `IntegerIndexedObjectCreate ( prototype )`
///
/// Create a new `JsObject` from a prototype and a `IntergetIndexedObject`
/// Create a new `JsObject` from a prototype and a `IntegerIndexedObject`
///
/// More information:
/// - [ECMAScript reference][spec]
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/bytecompiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ impl<'b> ByteCompiler<'b> {

#[inline]
fn pop_loop_control_info(&mut self) {
let loop_info = self.jump_info.pop().expect("no jump informatiojn found");
let loop_info = self.jump_info.pop().expect("no jump information found");

assert!(loop_info.kind == JumpControlInfoKind::Loop);

Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
//! Ok(animal)
//! }
//!
//! /// This is where the object is intitialized.
//! /// This is where the object is initialized.
//! fn init(class: &mut ClassBuilder) -> JsResult<()> {
//! class.method("speak", 0, |this, _args, _ctx| {
//! if let Some(object) = this.as_object() {
Expand Down Expand Up @@ -74,7 +74,7 @@ pub trait Class: NativeObject + Sized {
const NAME: &'static str;
/// The amount of arguments the class `constructor` takes, default is `0`.
const LENGTH: usize = 0;
/// The attibutes the class will be binded with, default is `writable`, `enumerable`, `configurable`.
/// The attributes the class will be binded with, default is `writable`, `enumerable`, `configurable`.
const ATTRIBUTES: Attribute = Attribute::all();

/// The constructor of the class.
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/object/jsarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl JsArray {
Self { inner }
}

/// Create an array from a `IntoIterator<Item = JsValue>` convertable object.
/// Create an array from a `IntoIterator<Item = JsValue>` convertible object.
#[inline]
pub fn from_iter<I>(elements: I, context: &mut Context) -> Self
where
Expand Down
22 changes: 22 additions & 0 deletions boa_engine/src/object/jsobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,28 @@ impl JsObject {
self.borrow().is_map_iterator()
}

/// Checks if it is a `Set` object
///
/// # Panics
///
/// Panics if the object is currently mutably borrowed.
#[inline]
#[track_caller]
pub fn is_set(&self) -> bool {
self.borrow().is_set()
}

/// Checks if it is a `SetIterator` object
///
/// # Panics
///
/// Panics if the object is currently mutably borrowed.
#[inline]
#[track_caller]
pub fn is_set_iterator(&self) -> bool {
self.borrow().is_set_iterator()
}

/// Checks if it's a `String` object.
///
/// # Panics
Expand Down
Loading

0 comments on commit 52bc15b

Please sign in to comment.