From 1547e7a7d72efd7f2d0cc64f65998ff5161f38ae Mon Sep 17 00:00:00 2001 From: Jason Williams Date: Fri, 6 Mar 2020 23:27:48 +0000 Subject: [PATCH 1/3] Addition of forEach() --- .vscode/launch.json | 2 +- .vscode/tasks.json | 6 +++++ boa/src/builtins/array/mod.rs | 29 +++++++++++++++++++++- boa/src/builtins/array/tests.rs | 44 +++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ef1ff5b79fa..1542244a90d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "type": "lldb", "request": "launch", "name": "Launch", - "program": "${workspaceFolder}/target/debug/boa_cli", + "program": "${workspaceFolder}/target/debug/boa_cli.exe", "sourceLanguages": ["rust"] }, { diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f40039aa0bb..24985f5fedd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -12,6 +12,9 @@ "group": { "kind": "build", "isDefault": true + }, + "presentation": { + "clear": true } }, { @@ -23,6 +26,9 @@ "group": { "kind": "test", "isDefault": true + }, + "presentation": { + "clear": true } } ] diff --git a/boa/src/builtins/array/mod.rs b/boa/src/builtins/array/mod.rs index 1dcd95761aa..3ae5751ba96 100644 --- a/boa/src/builtins/array/mod.rs +++ b/boa/src/builtins/array/mod.rs @@ -206,6 +206,33 @@ pub fn pop(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue { Ok(pop_value) } +/// Array.prototype.forEach ( callbackFn [ , thisArg ] ) +/// +/// This method executes the provided callback function for each element in the array. +/// +pub fn for_each(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> ResultValue { + if args.is_empty() { + return Err(to_value( + "Missing argument for Array.prototype.forEach".to_string(), + )); + } + + let callback_arg = args.get(0).expect("Could not get `callbackFn` argument."); + let this_arg = args.get(1).cloned().unwrap_or_else(undefined); + + let length: i32 = + from_value(this.get_field_slice("length")).expect("Could not get `length` property."); + + for i in 0..length { + let element = this.get_field_slice(&i.to_string()); + let arguments = vec![element.clone(), to_value(i), this.clone()]; + + interpreter.call(callback_arg, &this_arg, arguments)?; + } + + Ok(Gc::new(ValueData::Undefined)) +} + /// Array.prototype.join ( separator ) /// /// The elements of the array are converted to Strings, and these Strings are @@ -732,7 +759,7 @@ pub fn create_constructor(global: &Value) -> Value { make_builtin_fn!(includes_value, named "includes", with length 1, of array_prototype); make_builtin_fn!(map, named "map", with length 1, of array_prototype); make_builtin_fn!(fill, named "fill", with length 1, of array_prototype); - + make_builtin_fn!(for_each, named "forEach", with length 1, of array_prototype); make_builtin_fn!(pop, named "pop", of array_prototype); make_builtin_fn!(join, named "join", with length 1, of array_prototype); make_builtin_fn!(to_string, named "toString", of array_prototype); diff --git a/boa/src/builtins/array/tests.rs b/boa/src/builtins/array/tests.rs index 5e88ff5f7f6..ed25220360e 100644 --- a/boa/src/builtins/array/tests.rs +++ b/boa/src/builtins/array/tests.rs @@ -631,3 +631,47 @@ fn slice() { assert_eq!(forward(&mut engine, "many2.length"), "1"); assert_eq!(forward(&mut engine, "many3.length"), "0"); } + +#[test] +fn for_each() { + let realm = Realm::create(); + let mut engine = Executor::new(realm); + let init = r#" + var a = [2, 3, 4, 5]; + var sum = 0; + var indexSum = 0; + var listLengthSum = 0; + function callingCallback(item, index, list) { + sum += item; + indexSum += index; + listLengthSum += list.length; + } + a.forEach(callingCallback); + "#; + forward(&mut engine, init); + + assert_eq!(forward(&mut engine, "sum"), "14"); + assert_eq!(forward(&mut engine, "indexSum"), "6"); + assert_eq!(forward(&mut engine, "listLengthSum"), "16"); +} + +#[test] +fn for_each_push_value() { + let realm = Realm::create(); + let mut engine = Executor::new(realm); + let init = r#" + var a = [1, 2, 3, 4]; + function callingCallback(item, index, list) { + list.push(item * 2); + } + a.forEach(callingCallback); + "#; + forward(&mut engine, init); + + // [ 1, 2, 3, 4, 2, 4, 6, 8 ] + assert_eq!(forward(&mut engine, "a.length"), "8"); + assert_eq!(forward(&mut engine, "a[4]"), "2"); + assert_eq!(forward(&mut engine, "a[5]"), "4"); + assert_eq!(forward(&mut engine, "a[6]"), "6"); + assert_eq!(forward(&mut engine, "a[7]"), "8"); +} From b648ebb23f37007785dd7eeee3e00efe25097544 Mon Sep 17 00:00:00 2001 From: Jason Williams Date: Sun, 8 Mar 2020 21:10:02 +0000 Subject: [PATCH 2/3] windows needs .exe --- .vscode/launch.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 1542244a90d..3d690e02929 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,12 @@ "type": "lldb", "request": "launch", "name": "Launch", - "program": "${workspaceFolder}/target/debug/boa_cli.exe", + "windows": { + "program": "${workspaceFolder}/target/debug/boa_cli.exe" + }, + "osx": { + "program": "${workspaceFolder}/target/debug/boa_cli" + }, "sourceLanguages": ["rust"] }, { From 23342da30a2669a7a15d320807e93365b58e8f06 Mon Sep 17 00:00:00 2001 From: Jason Williams Date: Sun, 8 Mar 2020 21:14:38 +0000 Subject: [PATCH 3/3] fixing LLDB launcher for windows --- .vscode/launch.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 3d690e02929..ca9e95998e8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,15 +11,15 @@ "windows": { "program": "${workspaceFolder}/target/debug/boa_cli.exe" }, - "osx": { - "program": "${workspaceFolder}/target/debug/boa_cli" - }, + "program": "${workspaceFolder}/target/debug/boa_cli", + "args": ["${workspaceFolder}/tests/js/test.js"], "sourceLanguages": ["rust"] }, { "name": "(Windows) Launch", "type": "cppvsdbg", "request": "launch", + "args": ["${workspaceFolder}/tests/js/test.js"], "program": "${workspaceFolder}/target/debug/boa_cli.exe", "cwd": "${workspaceFolder}", "sourceFileMap": {