Skip to content

Commit

Permalink
Fix 2 bugs that stopped test262 (#812)
Browse files Browse the repository at this point in the history
* Fix: Add check for length in Array.prototype.map

* Fix: Make Array.prototype.reduceRight work for length 1

* Refactor: Cleanup Array.prototype.map to use usize for length
  • Loading branch information
RageKnify authored Oct 8, 2020
1 parent a77ceb6 commit 9d4c49c
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ impl Array {
///
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype.map
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
pub(crate) fn map(this: &Value, args: &[Value], interpreter: &mut Context) -> Result<Value> {
pub(crate) fn map(this: &Value, args: &[Value], context: &mut Context) -> Result<Value> {
if args.is_empty() {
return Err(Value::from(
"missing argument 0 when calling function Array.prototype.map",
Expand All @@ -591,16 +591,20 @@ impl Array {
let callback = args.get(0).cloned().unwrap_or_else(Value::undefined);
let this_val = args.get(1).cloned().unwrap_or_else(Value::undefined);

let length = this.get_field("length").as_number().unwrap() as i32;
let length = this.get_field("length").to_length(context)?;

let new = Self::new_array(interpreter)?;
if length > 2usize.pow(32) - 1 {
return context.throw_range_error("Invalid array length");
}

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

let values: Vec<Value> = (0..length)
.map(|idx| {
let element = this.get_field(idx);
let args = [element, Value::from(idx), new.clone()];

interpreter
context
.call(&callback, &this_val, &args)
.unwrap_or_else(|_| Value::undefined())
})
Expand Down Expand Up @@ -1113,12 +1117,13 @@ impl Array {
);
}
let result = this.get_field(k);
k -= 1;
k = k.overflowing_sub(1).0;
result
} else {
initial_value
};
loop {
// usize::MAX is bigger than the maximum array size so we can use it check for integer undeflow
while k != usize::MAX {
if this.has_field(k) {
let arguments = [accumulator, this.get_field(k), Value::from(k), this.clone()];
accumulator = interpreter.call(&callback, &Value::undefined(), &arguments)?;
Expand All @@ -1140,7 +1145,7 @@ impl Array {
if k == 0 {
break;
}
k -= 1;
k = k.overflowing_sub(1).0;
}
Ok(accumulator)
}
Expand Down

0 comments on commit 9d4c49c

Please sign in to comment.