From f8b1997cc495f514405317ce6fce090e1b8d81e1 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Fri, 1 Oct 2021 22:08:25 -0400 Subject: [PATCH 01/17] Initial commit of comments and function --- boa/src/builtins/array/mod.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index e79683cb1af..2c71a3b1af7 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -487,6 +487,20 @@ impl Array { Ok(a.into()) } + ///'Array.prototype.at(index)' + /// + /// When at method is called with desired index, it returns the value at given + /// index. If index is invalid, the at method returns undefined. + /// + /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.at + /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at + pub(crate) fn at(this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { + //let O be ? ToObject(this value) + let obj = this.to_object(context)?; + + Ok() + } + /// `Array.prototype.concat(...arguments)` /// /// When the concat method is called with zero or more arguments, it returns an From b2a835f2ed13642933d514990d74709fecf1677d Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Fri, 1 Oct 2021 22:14:36 -0400 Subject: [PATCH 02/17] Adding ECMAScript step comment outlines --- boa/src/builtins/array/mod.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 2c71a3b1af7..73994d2cf24 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -492,12 +492,23 @@ impl Array { /// When at method is called with desired index, it returns the value at given /// index. If index is invalid, the at method returns undefined. /// + /// More information: + /// - [ECMAScript reference][spec] + /// - [MDN documentation][mdn] + /// /// [spec]: https://tc39.es/ecma262/#sec-array.prototype.at /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at pub(crate) fn at(this: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult { - //let O be ? ToObject(this value) + //1. let O be ? ToObject(this value) let obj = this.to_object(context)?; - + //2. let len be ? LengthOfArrayLike(O) + //3. let relativeIndex be ? ToIntegerOrInfinity(index) + //4. if relativeIndex >= 0, then + //a. let k be relativeIndex + //5. Else, + //a. let k be len + relativeIndex + //6. if k <0> or k >= len, return undefined + //7. Return ? Get(O, !ToString(𝔽(k))) Ok() } From 270508db3676a1bfd085e83a199685e950446dc7 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Fri, 1 Oct 2021 22:33:27 -0400 Subject: [PATCH 03/17] code written for all steps - comments reformatted --- boa/src/builtins/array/mod.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 73994d2cf24..e6bc3a46d7c 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -502,14 +502,27 @@ impl Array { //1. let O be ? ToObject(this value) let obj = this.to_object(context)?; //2. let len be ? LengthOfArrayLike(O) + let len = obj.length_of_array_like(context)?; //3. let relativeIndex be ? ToIntegerOrInfinity(index) - //4. if relativeIndex >= 0, then - //a. let k be relativeIndex - //5. Else, - //a. let k be len + relativeIndex - //6. if k <0> or k >= len, return undefined - //7. Return ? Get(O, !ToString(𝔽(k))) - Ok() + let relativeIndex = args.get(0).unwrap().to_integer_or_infinity(context)?; + let k = match relativeIndex { + //4. if relativeIndex >= 0, then let k be relativeIndex + IntegerOrInfinity::Integer(i) if i >= 0 => i, + //5. Else, let k be len + relativeIndex + IntegerOrInfinity::Integer(i) => len + i, + //handle most likely impossible case of + //IntegerOrInfinity::NegativeInfinity | IntegerOrInfinity::PositiveInfinity + //by setting to len which will return undefined + _ => len, + }; + //6. if k < 0 or k >= len, + if k < 0 || k >= len { + //return undefined + Ok(JsValue::undefined()) + } else { + //7. Return ? Get(O, !ToString(𝔽(k))) + obj.get(k, context)? + } } /// `Array.prototype.concat(...arguments)` From 7464179d92575ff9af5f305f92dbbdded83a9dda Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Fri, 1 Oct 2021 22:36:58 -0400 Subject: [PATCH 04/17] Added extra | to comment --- boa/src/builtins/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index e6bc3a46d7c..1c7d341d202 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -511,7 +511,7 @@ impl Array { //5. Else, let k be len + relativeIndex IntegerOrInfinity::Integer(i) => len + i, //handle most likely impossible case of - //IntegerOrInfinity::NegativeInfinity | IntegerOrInfinity::PositiveInfinity + //IntegerOrInfinity::NegativeInfinity || IntegerOrInfinity::PositiveInfinity //by setting to len which will return undefined _ => len, }; From be10c9fb0d25381fa43a7bd662c01b22a5e53191 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Fri, 1 Oct 2021 22:39:39 -0400 Subject: [PATCH 05/17] Cleaning up comments on match _ arm --- boa/src/builtins/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 1c7d341d202..7a8a69bfcb8 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -512,7 +512,7 @@ impl Array { IntegerOrInfinity::Integer(i) => len + i, //handle most likely impossible case of //IntegerOrInfinity::NegativeInfinity || IntegerOrInfinity::PositiveInfinity - //by setting to len which will return undefined + //by setting k to len which will return undefined below _ => len, }; //6. if k < 0 or k >= len, From db5725ac2752b4cccaf3781166ca75d7f0e8a9e3 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Fri, 1 Oct 2021 22:45:39 -0400 Subject: [PATCH 06/17] Updated top level comment block --- boa/src/builtins/array/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 7a8a69bfcb8..a4feaa6d7d3 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -489,8 +489,9 @@ impl Array { ///'Array.prototype.at(index)' /// - /// When at method is called with desired index, it returns the value at given - /// index. If index is invalid, the at method returns undefined. + /// When at method takes desired integer as index and returns the value at given + /// index. Negative integer counts backwards. If index is invalid, the at method + /// returns undefined. /// /// More information: /// - [ECMAScript reference][spec] From 07aebb95a8ed51e290e6ab87011e961a920d176c Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Fri, 1 Oct 2021 22:50:02 -0400 Subject: [PATCH 07/17] Added at method to constructor's prototype at line 89 --- boa/src/builtins/array/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index a4feaa6d7d3..b0eeb3d019d 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -86,6 +86,7 @@ impl BuiltIn for Array { values_function, Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, ) + .method(Self::at, "at", 1) .method(Self::concat, "concat", 1) .method(Self::push, "push", 1) .method(Self::index_of, "indexOf", 1) From 138a755aa1fc520bbf538395bdc11ce4e9fa026a Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 11:13:15 -0400 Subject: [PATCH 08/17] Fixing some errors involving len being usize and return type --- boa/src/builtins/array/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index b0eeb3d019d..b4c2ace881a 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -504,7 +504,7 @@ impl Array { //1. let O be ? ToObject(this value) let obj = this.to_object(context)?; //2. let len be ? LengthOfArrayLike(O) - let len = obj.length_of_array_like(context)?; + let len = obj.length_of_array_like(context)? as i64; //3. let relativeIndex be ? ToIntegerOrInfinity(index) let relativeIndex = args.get(0).unwrap().to_integer_or_infinity(context)?; let k = match relativeIndex { @@ -523,7 +523,7 @@ impl Array { Ok(JsValue::undefined()) } else { //7. Return ? Get(O, !ToString(𝔽(k))) - obj.get(k, context)? + obj.get(k, context) } } From f9bb0ac983c103dec672ad12697340638c1c8dd3 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 11:14:50 -0400 Subject: [PATCH 09/17] changed relativeIndex to relative_index for rust --- boa/src/builtins/array/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index b4c2ace881a..9c04c73f6f4 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -506,8 +506,8 @@ impl Array { //2. let len be ? LengthOfArrayLike(O) let len = obj.length_of_array_like(context)? as i64; //3. let relativeIndex be ? ToIntegerOrInfinity(index) - let relativeIndex = args.get(0).unwrap().to_integer_or_infinity(context)?; - let k = match relativeIndex { + let relative_index = args.get(0).unwrap().to_integer_or_infinity(context)?; + let k = match relative_index { //4. if relativeIndex >= 0, then let k be relativeIndex IntegerOrInfinity::Integer(i) if i >= 0 => i, //5. Else, let k be len + relativeIndex From 57b51ce89df625780b662abfd8da770473983e51 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 12:40:50 -0400 Subject: [PATCH 10/17] return 0 index by default in the case of no args given --- boa/src/builtins/array/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 9c04c73f6f4..05e3515340a 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -505,8 +505,10 @@ impl Array { let obj = this.to_object(context)?; //2. let len be ? LengthOfArrayLike(O) let len = obj.length_of_array_like(context)? as i64; + //handle unwrap() panicking on no input -> returns 0 index by default on at() + let arg_index = args.get(0).unwrap_or(&JsValue::new(0)).clone(); //3. let relativeIndex be ? ToIntegerOrInfinity(index) - let relative_index = args.get(0).unwrap().to_integer_or_infinity(context)?; + let relative_index = arg_index.to_integer_or_infinity(context)?; let k = match relative_index { //4. if relativeIndex >= 0, then let k be relativeIndex IntegerOrInfinity::Integer(i) if i >= 0 => i, From 1a9c4a986e559dfcd99a3b0f07f97f468d1a76a8 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 12:49:46 -0400 Subject: [PATCH 11/17] fixed comment on change for better readability --- boa/src/builtins/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 05e3515340a..213c97727b1 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -505,7 +505,7 @@ impl Array { let obj = this.to_object(context)?; //2. let len be ? LengthOfArrayLike(O) let len = obj.length_of_array_like(context)? as i64; - //handle unwrap() panicking on no input -> returns 0 index by default on at() + //fetch provided index, defaults to 0 index by default on at() let arg_index = args.get(0).unwrap_or(&JsValue::new(0)).clone(); //3. let relativeIndex be ? ToIntegerOrInfinity(index) let relative_index = arg_index.to_integer_or_infinity(context)?; From 18e26e39f082be82d0c618d993ff0a9d90790dc3 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 12:59:50 -0400 Subject: [PATCH 12/17] made changes according to review feedback --- boa/src/builtins/array/mod.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 213c97727b1..6e340e7f782 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -490,9 +490,10 @@ impl Array { ///'Array.prototype.at(index)' /// - /// When at method takes desired integer as index and returns the value at given - /// index. Negative integer counts backwards. If index is invalid, the at method - /// returns undefined. + /// The at() method takes an integer value and returns the + /// item at that index, allowing for positive and negative + /// integers. Negative integers count back from the last + /// item in the array. /// /// More information: /// - [ECMAScript reference][spec] @@ -505,10 +506,8 @@ impl Array { let obj = this.to_object(context)?; //2. let len be ? LengthOfArrayLike(O) let len = obj.length_of_array_like(context)? as i64; - //fetch provided index, defaults to 0 index by default on at() - let arg_index = args.get(0).unwrap_or(&JsValue::new(0)).clone(); //3. let relativeIndex be ? ToIntegerOrInfinity(index) - let relative_index = arg_index.to_integer_or_infinity(context)?; + let relative_index = args.get_or_undefined(0).to_integer_or_infinity(context)?; let k = match relative_index { //4. if relativeIndex >= 0, then let k be relativeIndex IntegerOrInfinity::Integer(i) if i >= 0 => i, @@ -516,8 +515,8 @@ impl Array { IntegerOrInfinity::Integer(i) => len + i, //handle most likely impossible case of //IntegerOrInfinity::NegativeInfinity || IntegerOrInfinity::PositiveInfinity - //by setting k to len which will return undefined below - _ => len, + //by returning undefined + _ => return Ok(JsValue::undefined()), }; //6. if k < 0 or k >= len, if k < 0 || k >= len { From 224dc93fccc2658284955edf4a2c112812de7d0c Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 13:01:09 -0400 Subject: [PATCH 13/17] updated comment block lines for readability --- boa/src/builtins/array/mod.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 6e340e7f782..945662c8f17 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -490,10 +490,9 @@ impl Array { ///'Array.prototype.at(index)' /// - /// The at() method takes an integer value and returns the - /// item at that index, allowing for positive and negative - /// integers. Negative integers count back from the last - /// item in the array. + /// The at() method takes an integer value and returns the item at that + /// index, allowing for positive and negative integers. Negative integers + /// count back from the last item in the array. /// /// More information: /// - [ECMAScript reference][spec] From e11bfc4122ecb14f97720e6b37d1174346145ce7 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 13:16:23 -0400 Subject: [PATCH 14/17] adding match guard update - removes need of step 6 --- boa/src/builtins/array/mod.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 945662c8f17..971b4a732d3 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -509,22 +509,20 @@ impl Array { let relative_index = args.get_or_undefined(0).to_integer_or_infinity(context)?; let k = match relative_index { //4. if relativeIndex >= 0, then let k be relativeIndex - IntegerOrInfinity::Integer(i) if i >= 0 => i, + //check if positive and if below length of array + IntegerOrInfinity::Integer(i) if i >= 0 && i < len => i, //5. Else, let k be len + relativeIndex - IntegerOrInfinity::Integer(i) => len + i, + //should be negative, so abs() and check if less than or equal to length of array + IntegerOrInfinity::Integer(i) if i.abs() <= len => len + i, //handle most likely impossible case of //IntegerOrInfinity::NegativeInfinity || IntegerOrInfinity::PositiveInfinity //by returning undefined _ => return Ok(JsValue::undefined()), }; //6. if k < 0 or k >= len, - if k < 0 || k >= len { - //return undefined - Ok(JsValue::undefined()) - } else { - //7. Return ? Get(O, !ToString(𝔽(k))) - obj.get(k, context) - } + //handled by the above match guards + //7. Return ? Get(O, !ToString(𝔽(k))) + obj.get(k, context) } /// `Array.prototype.concat(...arguments)` From 753f517a6989b1e647f909fc77e7daa096b7f455 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 13:18:44 -0400 Subject: [PATCH 15/17] clean up comments on match guards --- boa/src/builtins/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 971b4a732d3..0076879267e 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -512,7 +512,7 @@ impl Array { //check if positive and if below length of array IntegerOrInfinity::Integer(i) if i >= 0 && i < len => i, //5. Else, let k be len + relativeIndex - //should be negative, so abs() and check if less than or equal to length of array + //integer should be negative, so abs() and check if less than or equal to length of array IntegerOrInfinity::Integer(i) if i.abs() <= len => len + i, //handle most likely impossible case of //IntegerOrInfinity::NegativeInfinity || IntegerOrInfinity::PositiveInfinity From 1acc870b290663876ae7259937400081a86d69e2 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 13:40:22 -0400 Subject: [PATCH 16/17] fixing potential match bug involving arg being len --- boa/src/builtins/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 0076879267e..798f79470b7 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -513,7 +513,7 @@ impl Array { IntegerOrInfinity::Integer(i) if i >= 0 && i < len => i, //5. Else, let k be len + relativeIndex //integer should be negative, so abs() and check if less than or equal to length of array - IntegerOrInfinity::Integer(i) if i.abs() <= len => len + i, + IntegerOrInfinity::Integer(i) if i.abs() <= len && i != len => len + i, //handle most likely impossible case of //IntegerOrInfinity::NegativeInfinity || IntegerOrInfinity::PositiveInfinity //by returning undefined From 0a6d4ebbb91e4b90a56c2f0d97e63cfd093cf7a8 Mon Sep 17 00:00:00 2001 From: nekevss <46825870+nekevss@users.noreply.github.com> Date: Sat, 2 Oct 2021 22:47:28 -0400 Subject: [PATCH 17/17] logic update to match guard on second arm for readability --- boa/src/builtins/array/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 798f79470b7..3807b00c2e2 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -513,7 +513,7 @@ impl Array { IntegerOrInfinity::Integer(i) if i >= 0 && i < len => i, //5. Else, let k be len + relativeIndex //integer should be negative, so abs() and check if less than or equal to length of array - IntegerOrInfinity::Integer(i) if i.abs() <= len && i != len => len + i, + IntegerOrInfinity::Integer(i) if i < 0 && i.abs() <= len => len + i, //handle most likely impossible case of //IntegerOrInfinity::NegativeInfinity || IntegerOrInfinity::PositiveInfinity //by returning undefined