@@ -2088,8 +2088,77 @@ impl ArrayPrototype {
20882088 Ok ( accumulator)
20892089 }
20902090
2091- fn reverse ( _agent : & mut Agent , _this_value : Value , _: ArgumentsList ) -> JsResult < Value > {
2092- todo ! ( )
2091+ fn reverse ( agent : & mut Agent , this_value : Value , _: ArgumentsList ) -> JsResult < Value > {
2092+ if let Value :: Array ( array) = this_value {
2093+ // Fast path: Array is dense and contains no descriptors. No JS
2094+ // functions can thus be called by shift.
2095+ if array. is_trivial ( agent) && array. is_dense ( agent) {
2096+ array. as_mut_slice ( agent) . reverse ( ) ;
2097+ return Ok ( array. into_value ( ) ) ;
2098+ }
2099+ }
2100+
2101+ // 1. Let O be ? ToObject(this value).
2102+ let o = to_object ( agent, this_value) ?;
2103+ // 2. Let len be ? LengthOfArrayLike(O).
2104+ let len = length_of_array_like ( agent, o) ?;
2105+ // 3. Let middle be floor(len / 2).
2106+ let middle = len / 2 ;
2107+ // 4. Let lower be 0.
2108+ let mut lower: i64 = 0 ;
2109+ // 5. Repeat, while lower ≠ middle,
2110+ while lower != middle {
2111+ // a. Let upper be len - lower - 1.
2112+ let upper = len - lower - 1 ;
2113+ // b. Let upperP be ! ToString(𝔽(upper)).
2114+ let upper_p = PropertyKey :: Integer ( upper. try_into ( ) . unwrap ( ) ) ;
2115+ // c. Let lowerP be ! ToString(𝔽(lower)).
2116+ let lower_p = PropertyKey :: Integer ( lower. try_into ( ) . unwrap ( ) ) ;
2117+ // d. Let lowerExists be ? HasProperty(O, lowerP).
2118+ // e. If lowerExists is true, then
2119+ // i. Let lowerValue be ? Get(O, lowerP).
2120+ let lower_exists = has_property ( agent, o, lower_p) ?;
2121+ // f. Let upperExists be ? HasProperty(O, upperP).
2122+ // g. If upperExists is true, then
2123+ // i. Let upperValue be ? Get(O, upperP).
2124+ let upper_exists = has_property ( agent, o, upper_p) ?;
2125+
2126+ // h. If lowerExists is true and upperExists is true, then
2127+ if lower_exists && upper_exists {
2128+ // i. Perform ? Set(O, lowerP, upperValue, true).
2129+ // ii. Perform ? Set(O, upperP, lowerValue, true).
2130+ let lower_value = get ( agent, o, lower_p) ?;
2131+ let upper_value = get ( agent, o, upper_p) ?;
2132+ set ( agent, o, lower_p, upper_value, true ) ?;
2133+ set ( agent, o, upper_p, lower_value, true ) ?;
2134+ }
2135+ // i. Else if lowerExists is false and upperExists is true, then
2136+ else if !lower_exists && upper_exists {
2137+ // i. Perform ? Set(O, lowerP, upperValue, true).
2138+ // ii. Perform ? DeletePropertyOrThrow(O, upperP).
2139+ let upper_value = get ( agent, o, upper_p) ?;
2140+ set ( agent, o, lower_p, upper_value, true ) ?;
2141+ delete_property_or_throw ( agent, o, upper_p) ?;
2142+ }
2143+ // j. Else if lowerExists is true and upperExists is false, then
2144+ else if lower_exists && !upper_exists {
2145+ // i. Perform ? DeletePropertyOrThrow(O, lowerP).
2146+ // ii. Perform ? Set(O, upperP, lowerValue, true).
2147+ let lower_value = get ( agent, o, lower_p) ?;
2148+ delete_property_or_throw ( agent, o, lower_p) ?;
2149+ set ( agent, o, upper_p, lower_value, true ) ?;
2150+ }
2151+ // k. Else,
2152+ else {
2153+ // i. Assert: lowerExists and upperExists are both false.
2154+ // ii. NOTE: No action is required.
2155+ assert ! ( !( lower_exists && upper_exists) ) ;
2156+ }
2157+ // l. Set lower to lower + 1.
2158+ lower += 1 ;
2159+ }
2160+ // 6. Return O.
2161+ Ok ( o. into_value ( ) )
20932162 }
20942163
20952164 /// ### [23.1.3.27 Array.prototype.shift ( )](https://tc39.es/ecma262/#sec-array.prototype.shift)
0 commit comments