Skip to content

Commit

Permalink
Merge f94e23b into 9e0cab5
Browse files Browse the repository at this point in the history
  • Loading branch information
RageKnify authored Feb 16, 2021
2 parents 9e0cab5 + f94e23b commit 5d4c262
Show file tree
Hide file tree
Showing 31 changed files with 1,193 additions and 108 deletions.
4 changes: 2 additions & 2 deletions boa/src/builtins/array/array_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ impl ArrayIterator {
context: &Context,
array: Value,
kind: ArrayIterationKind,
) -> Result<Value> {
) -> Value {
let array_iterator = Value::new_object(context);
array_iterator.set_data(ObjectData::ArrayIterator(Self::new(array, kind)));
array_iterator
.as_object()
.expect("array iterator object")
.set_prototype_instance(context.iterator_prototypes().array_iterator().into());
Ok(array_iterator)
array_iterator
}

/// %ArrayIteratorPrototype%.next( )
Expand Down
44 changes: 26 additions & 18 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl Array {
.unwrap_or_else(|| context.standard_objects().array_object().prototype());
// Delegate to the appropriate constructor based on the number of arguments
match args.len() {
0 => Array::construct_array_empty(prototype, context),
0 => Ok(Array::construct_array_empty(prototype, context)),
1 => Array::construct_array_length(prototype, &args[0], context),
_ => Array::construct_array_values(prototype, args, context),
}
Expand All @@ -132,7 +132,7 @@ impl Array {
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-array-constructor-array
fn construct_array_empty(proto: GcObject, context: &mut Context) -> Result<Value> {
fn construct_array_empty(proto: GcObject, context: &mut Context) -> Value {
Array::array_create(0, Some(proto), context)
}

Expand All @@ -147,7 +147,7 @@ impl Array {
length: &Value,
context: &mut Context,
) -> Result<Value> {
let array = Array::array_create(0, Some(prototype), context)?;
let array = Array::array_create(0, Some(prototype), context);

if !length.is_number() {
array.set_property(0, DataDescriptor::new(length, Attribute::all()));
Expand All @@ -174,7 +174,7 @@ impl Array {
context: &mut Context,
) -> Result<Value> {
let items_len = items.len().try_into().map_err(interror_to_value)?;
let array = Array::array_create(items_len, Some(prototype), context)?;
let array = Array::array_create(items_len, Some(prototype), context);

for (k, item) in items.iter().enumerate() {
array.set_property(k, DataDescriptor::new(item.clone(), Attribute::all()));
Expand All @@ -189,11 +189,7 @@ impl Array {
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-arraycreate
fn array_create(
length: u32,
prototype: Option<GcObject>,
context: &mut Context,
) -> Result<Value> {
fn array_create(length: u32, prototype: Option<GcObject>, context: &mut Context) -> Value {
let prototype = match prototype {
Some(prototype) => prototype,
None => context.standard_objects().array_object().prototype(),
Expand All @@ -214,11 +210,11 @@ impl Array {
);
array.set_property("length", length);

Ok(array)
array
}

/// Creates a new `Array` instance.
pub(crate) fn new_array(context: &Context) -> Result<Value> {
pub(crate) fn new_array(context: &Context) -> Value {
let array = Value::new_object(context);
array.set_data(ObjectData::Array);
array
Expand All @@ -230,7 +226,7 @@ impl Array {
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::PERMANENT,
);
array.set_property("length", length);
Ok(array)
array
}

/// Utility function for creating array objects.
Expand Down Expand Up @@ -682,7 +678,7 @@ impl Array {
return context.throw_range_error("Invalid array length");
}

let new = Self::new_array(context)?;
let new = Self::new_array(context);

let values = (0..length)
.map(|idx| {
Expand Down Expand Up @@ -960,7 +956,7 @@ impl Array {
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype.slice
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
pub(crate) fn slice(this: &Value, args: &[Value], context: &mut Context) -> Result<Value> {
let new_array = Self::new_array(context)?;
let new_array = Self::new_array(context);

let len = this.get_field("length", context)?.to_length(context)?;
let from = Self::get_relative_start(context, args.get(0), len)?;
Expand Down Expand Up @@ -1005,7 +1001,7 @@ impl Array {

let length = this.get_field("length", context)?.to_length(context)?;

let new = Self::new_array(context)?;
let new = Self::new_array(context);

let values = (0..length)
.map(|idx| {
Expand Down Expand Up @@ -1245,7 +1241,11 @@ impl Array {
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype.values
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values
pub(crate) fn values(this: &Value, _: &[Value], context: &mut Context) -> Result<Value> {
ArrayIterator::create_array_iterator(context, this.clone(), ArrayIterationKind::Value)
Ok(ArrayIterator::create_array_iterator(
context,
this.clone(),
ArrayIterationKind::Value,
))
}

/// `Array.prototype.keys( )`
Expand All @@ -1259,7 +1259,11 @@ impl Array {
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype.values
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values
pub(crate) fn keys(this: &Value, _: &[Value], context: &mut Context) -> Result<Value> {
ArrayIterator::create_array_iterator(context, this.clone(), ArrayIterationKind::Key)
Ok(ArrayIterator::create_array_iterator(
context,
this.clone(),
ArrayIterationKind::Key,
))
}

/// `Array.prototype.entries( )`
Expand All @@ -1273,7 +1277,11 @@ impl Array {
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype.values
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values
pub(crate) fn entries(this: &Value, _: &[Value], context: &mut Context) -> Result<Value> {
ArrayIterator::create_array_iterator(context, this.clone(), ArrayIterationKind::KeyAndValue)
Ok(ArrayIterator::create_array_iterator(
context,
this.clone(),
ArrayIterationKind::KeyAndValue,
))
}

/// Represents the algorithm to calculate `relativeStart` (or `k`) in array functions.
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/array/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1366,7 +1366,7 @@ fn get_relative_end() {
fn array_length_is_not_enumerable() {
let context = Context::new();

let array = Array::new_array(&context).unwrap();
let array = Array::new_array(&context);
let desc = array.get_property("length").unwrap();
assert!(!desc.enumerable());
}
12 changes: 6 additions & 6 deletions boa/src/builtins/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ impl Date {
context: &mut Context,
) -> Result<Value> {
if new_target.is_undefined() {
Self::make_date_string()
Ok(Self::make_date_string())
} else {
let prototype = new_target
.as_object()
Expand All @@ -386,7 +386,7 @@ impl Date {
obj.set_prototype_instance(prototype.into());
let this = obj.into();
if args.is_empty() {
Self::make_date_now(&this)
Ok(Self::make_date_now(&this))
} else if args.len() == 1 {
Self::make_date_single(&this, args, context)
} else {
Expand All @@ -405,8 +405,8 @@ impl Date {
///
/// [spec]: https://tc39.es/ecma262/#sec-date-constructor
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date
pub(crate) fn make_date_string() -> Result<Value> {
Ok(Value::from(Local::now().to_rfc3339()))
pub(crate) fn make_date_string() -> Value {
Value::from(Local::now().to_rfc3339())
}

/// `Date()`
Expand All @@ -419,10 +419,10 @@ impl Date {
///
/// [spec]: https://tc39.es/ecma262/#sec-date-constructor
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date
pub(crate) fn make_date_now(this: &Value) -> Result<Value> {
pub(crate) fn make_date_now(this: &Value) -> Value {
let date = Date::default();
this.set_data(ObjectData::Date(date));
Ok(this.clone())
this.clone()
}

/// `Date(value)`
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl Function {
local_env: &Environment,
) {
// Create array of values
let array = Array::new_array(context).unwrap();
let array = Array::new_array(context);
Array::add_to_array_object(&array, &args_list[index..], context).unwrap();

// Create binding
Expand Down
42 changes: 42 additions & 0 deletions boa/src/builtins/iterable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
builtins::ArrayIterator,
builtins::ForInIterator,
builtins::MapIterator,
builtins::SetIterator,
object::{GcObject, ObjectInitializer},
property::{Attribute, DataDescriptor},
BoaProfiler, Context, Result, Value,
Expand All @@ -12,6 +13,7 @@ use crate::{
pub struct IteratorPrototypes {
iterator_prototype: GcObject,
array_iterator: GcObject,
set_iterator: GcObject,
string_iterator: GcObject,
map_iterator: GcObject,
for_in_iterator: GcObject,
Expand All @@ -25,6 +27,7 @@ impl IteratorPrototypes {
context,
iterator_prototype.clone().into(),
),
set_iterator: SetIterator::create_prototype(context, iterator_prototype.clone().into()),
string_iterator: StringIterator::create_prototype(
context,
iterator_prototype.clone().into(),
Expand All @@ -48,6 +51,11 @@ impl IteratorPrototypes {
self.iterator_prototype.clone()
}

#[inline]
pub fn set_iterator(&self) -> GcObject {
self.set_iterator.clone()
}

#[inline]
pub fn string_iterator(&self) -> GcObject {
self.string_iterator.clone()
Expand Down Expand Up @@ -139,6 +147,40 @@ impl IteratorRecord {
let next_result = next.get_field("value", context)?;
Ok(IteratorResult::new(next_result, done))
}

/// Cleanup the iterator
///
/// More information:
/// - [ECMA reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-iteratorclose
pub(crate) fn close(&self, completion: Result<Value>, context: &mut Context) -> Result<Value> {
let mut inner_result = self.iterator_object.get_field("return", context);

// 5
if let Ok(inner_value) = inner_result {
// b
if inner_value.is_undefined() {
return completion;
}
// c
inner_result = context.call(&inner_value, &self.iterator_object, &[]);
}

// 6
let completion = completion?;

// 7
let inner_result = inner_result?;

// 8
if !inner_result.is_object() {
return context.throw_type_error("`return` method of iterator didn't return an Object");
}

// 9
Ok(completion)
}
}

#[derive(Debug)]
Expand Down
6 changes: 3 additions & 3 deletions boa/src/builtins/map/map_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ impl MapIterator {
context: &Context,
map: Value,
kind: MapIterationKind,
) -> Result<Value> {
) -> Value {
let map_iterator = Value::new_object(context);
map_iterator.set_data(ObjectData::MapIterator(Self::new(map, kind)));
map_iterator
.as_object()
.expect("map iterator object")
.set_prototype_instance(context.iterator_prototypes().map_iterator().into());
Ok(map_iterator)
map_iterator
}

/// %MapIteratorPrototype%.next( )
Expand Down Expand Up @@ -104,7 +104,7 @@ impl MapIterator {
}
MapIterationKind::KeyAndValue => {
let result = Array::construct_array(
&Array::new_array(context)?,
&Array::new_array(context),
&[key.clone(), value.clone()],
context,
)?;
Expand Down
23 changes: 17 additions & 6 deletions boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,14 @@ impl BuiltIn for Map {
.method(Self::has, "has", 1)
.method(Self::for_each, "forEach", 1)
.method(Self::values, "values", 0)
.callable(false)
.build();

(Self::NAME, map_object.into(), Self::attribute())
}
}

impl Map {
pub(crate) const LENGTH: usize = 1;
pub(crate) const LENGTH: usize = 0;

/// Create a new map
pub(crate) fn constructor(
Expand All @@ -75,7 +74,7 @@ impl Map {
context: &mut Context,
) -> Result<Value> {
if new_target.is_undefined() {
return context.throw_type_error("Map requires new");
return context.throw_type_error("Constructor Map requires 'new'");
}
let map_prototype = context
.global_object()
Expand Down Expand Up @@ -158,7 +157,11 @@ impl Map {
/// [spec]: https://www.ecma-international.org/ecma-262/11.0/index.html#sec-map.prototype.entries
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries
pub(crate) fn entries(this: &Value, _: &[Value], context: &mut Context) -> Result<Value> {
MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::KeyAndValue)
Ok(MapIterator::create_map_iterator(
context,
this.clone(),
MapIterationKind::KeyAndValue,
))
}

/// `Map.prototype.keys()`
Expand All @@ -172,7 +175,11 @@ impl Map {
/// [spec]: https://tc39.es/ecma262/#sec-map.prototype.keys
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys
pub(crate) fn keys(this: &Value, _: &[Value], context: &mut Context) -> Result<Value> {
MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::Key)
Ok(MapIterator::create_map_iterator(
context,
this.clone(),
MapIterationKind::Key,
))
}

/// Helper function to set the size property.
Expand Down Expand Up @@ -395,7 +402,11 @@ impl Map {
/// [spec]: https://tc39.es/ecma262/#sec-map.prototype.values
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values
pub(crate) fn values(this: &Value, _: &[Value], context: &mut Context) -> Result<Value> {
MapIterator::create_map_iterator(context, this.clone(), MapIterationKind::Value)
Ok(MapIterator::create_map_iterator(
context,
this.clone(),
MapIterationKind::Value,
))
}

/// Helper function to get a key-value pair from an array.
Expand Down
2 changes: 1 addition & 1 deletion boa/src/builtins/map/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,6 @@ fn not_a_function() {
";
assert_eq!(
forward(&mut context, init),
"\"TypeError: function object is not callable\""
"\"TypeError: Constructor Map requires 'new'\""
);
}
Loading

0 comments on commit 5d4c262

Please sign in to comment.